@@ -540,46 +540,53 @@ func ListIssueTypes(getClient GetClientFn, t translations.TranslationHelperFunc)
540540}
541541
542542// AddIssueComment creates a tool to add a comment to an issue.
543- func AddIssueComment (getClient GetClientFn , t translations.TranslationHelperFunc ) (tool mcp.Tool , handler server.ToolHandlerFunc ) {
544- return mcp .NewTool ("add_issue_comment" ,
545- mcp .WithDescription (t ("TOOL_ADD_ISSUE_COMMENT_DESCRIPTION" , "Add a comment to a specific issue in a GitHub repository. Use this tool to add comments to pull requests as well (in this case pass pull request number as issue_number), but only if user is not asking specifically to add review comments." )),
546- mcp .WithToolAnnotation (mcp.ToolAnnotation {
543+ func AddIssueComment (getClient GetClientFn , t translations.TranslationHelperFunc ) (mcp.Tool , mcp.ToolHandlerFor [map [string ]any , any ]) {
544+ return mcp.Tool {
545+ Name : "add_issue_comment" ,
546+ Description : t ("TOOL_ADD_ISSUE_COMMENT_DESCRIPTION" , "Add a comment to a specific issue in a GitHub repository. Use this tool to add comments to pull requests as well (in this case pass pull request number as issue_number), but only if user is not asking specifically to add review comments." ),
547+ Annotations : & mcp.ToolAnnotations {
547548 Title : t ("TOOL_ADD_ISSUE_COMMENT_USER_TITLE" , "Add comment to issue" ),
548- ReadOnlyHint : ToBoolPtr (false ),
549- }),
550- mcp .WithString ("owner" ,
551- mcp .Required (),
552- mcp .Description ("Repository owner" ),
553- ),
554- mcp .WithString ("repo" ,
555- mcp .Required (),
556- mcp .Description ("Repository name" ),
557- ),
558- mcp .WithNumber ("issue_number" ,
559- mcp .Required (),
560- mcp .Description ("Issue number to comment on" ),
561- ),
562- mcp .WithString ("body" ,
563- mcp .Required (),
564- mcp .Description ("Comment content" ),
565- ),
566- ),
567- func (ctx context.Context , request mcp.CallToolRequest ) (* mcp.CallToolResult , error ) {
568- owner , err := RequiredParam [string ](request , "owner" )
549+ ReadOnlyHint : false ,
550+ },
551+ InputSchema : & jsonschema.Schema {
552+ Type : "object" ,
553+ Properties : map [string ]* jsonschema.Schema {
554+ "owner" : {
555+ Type : "string" ,
556+ Description : "Repository owner" ,
557+ },
558+ "repo" : {
559+ Type : "string" ,
560+ Description : "Repository name" ,
561+ },
562+ "issue_number" : {
563+ Type : "number" ,
564+ Description : "Issue number to comment on" ,
565+ },
566+ "body" : {
567+ Type : "string" ,
568+ Description : "Comment content" ,
569+ },
570+ },
571+ Required : []string {"owner" , "repo" , "issue_number" , "body" },
572+ },
573+ },
574+ func (ctx context.Context , _ * mcp.CallToolRequest , args map [string ]any ) (* mcp.CallToolResult , any , error ) {
575+ owner , err := RequiredParam [string ](args , "owner" )
569576 if err != nil {
570- return mcp .NewToolResultError (err .Error ()), nil
577+ return utils .NewToolResultError (err .Error ()), nil , nil
571578 }
572- repo , err := RequiredParam [string ](request , "repo" )
579+ repo , err := RequiredParam [string ](args , "repo" )
573580 if err != nil {
574- return mcp .NewToolResultError (err .Error ()), nil
581+ return utils .NewToolResultError (err .Error ()), nil , nil
575582 }
576- issueNumber , err := RequiredInt (request , "issue_number" )
583+ issueNumber , err := RequiredInt (args , "issue_number" )
577584 if err != nil {
578- return mcp .NewToolResultError (err .Error ()), nil
585+ return utils .NewToolResultError (err .Error ()), nil , nil
579586 }
580- body , err := RequiredParam [string ](request , "body" )
587+ body , err := RequiredParam [string ](args , "body" )
581588 if err != nil {
582- return mcp .NewToolResultError (err .Error ()), nil
589+ return utils .NewToolResultError (err .Error ()), nil , nil
583590 }
584591
585592 comment := & github.IssueComment {
@@ -588,125 +595,138 @@ func AddIssueComment(getClient GetClientFn, t translations.TranslationHelperFunc
588595
589596 client , err := getClient (ctx )
590597 if err != nil {
591- return nil , fmt . Errorf ("failed to get GitHub client: %w " , err )
598+ return utils . NewToolResultErrorFromErr ("failed to get GitHub client" , err ), nil , nil
592599 }
593600 createdComment , resp , err := client .Issues .CreateComment (ctx , owner , repo , issueNumber , comment )
594601 if err != nil {
595- return nil , fmt . Errorf ("failed to create comment: %w " , err )
602+ return utils . NewToolResultErrorFromErr ("failed to create comment" , err ), nil , nil
596603 }
597604 defer func () { _ = resp .Body .Close () }()
598605
599606 if resp .StatusCode != http .StatusCreated {
600607 body , err := io .ReadAll (resp .Body )
601608 if err != nil {
602- return nil , fmt . Errorf ("failed to read response body: %w " , err )
609+ return utils . NewToolResultErrorFromErr ("failed to read response body" , err ), nil , nil
603610 }
604- return mcp .NewToolResultError (fmt .Sprintf ("failed to create comment: %s" , string (body ))), nil
611+ return utils .NewToolResultError (fmt .Sprintf ("failed to create comment: %s" , string (body ))), nil , nil
605612 }
606613
607614 r , err := json .Marshal (createdComment )
608615 if err != nil {
609- return nil , fmt . Errorf ("failed to marshal response: %w " , err )
616+ return utils . NewToolResultErrorFromErr ("failed to marshal response" , err ), nil , nil
610617 }
611618
612- return mcp .NewToolResultText (string (r )), nil
619+ return utils .NewToolResultText (string (r )), nil , nil
613620 }
614621}
615622
616623// SubIssueWrite creates a tool to add a sub-issue to a parent issue.
617- func SubIssueWrite (getClient GetClientFn , t translations.TranslationHelperFunc ) (tool mcp.Tool , handler server.ToolHandlerFunc ) {
618- return mcp .NewTool ("sub_issue_write" ,
619- mcp .WithDescription (t ("TOOL_SUB_ISSUE_WRITE_DESCRIPTION" , "Add a sub-issue to a parent issue in a GitHub repository." )),
620- mcp .WithToolAnnotation (mcp.ToolAnnotation {
624+ func SubIssueWrite (getClient GetClientFn , t translations.TranslationHelperFunc ) (mcp.Tool , mcp.ToolHandlerFor [map [string ]any , any ]) {
625+ return mcp.Tool {
626+ Name : "sub_issue_write" ,
627+ Description : t ("TOOL_SUB_ISSUE_WRITE_DESCRIPTION" , "Add a sub-issue to a parent issue in a GitHub repository." ),
628+ Annotations : & mcp.ToolAnnotations {
621629 Title : t ("TOOL_SUB_ISSUE_WRITE_USER_TITLE" , "Change sub-issue" ),
622- ReadOnlyHint : ToBoolPtr (false ),
623- }),
624- mcp .WithString ("method" ,
625- mcp .Required (),
626- mcp .Description (`The action to perform on a single sub-issue
630+ ReadOnlyHint : false ,
631+ },
632+ InputSchema : & jsonschema.Schema {
633+ Type : "object" ,
634+ Properties : map [string ]* jsonschema.Schema {
635+ "method" : {
636+ Type : "string" ,
637+ Description : `The action to perform on a single sub-issue
627638Options are:
628639- 'add' - add a sub-issue to a parent issue in a GitHub repository.
629640- 'remove' - remove a sub-issue from a parent issue in a GitHub repository.
630641- 'reprioritize' - change the order of sub-issues within a parent issue in a GitHub repository. Use either 'after_id' or 'before_id' to specify the new position.
631- ` ),
632- ),
633- mcp .WithString ("owner" ,
634- mcp .Required (),
635- mcp .Description ("Repository owner" ),
636- ),
637- mcp .WithString ("repo" ,
638- mcp .Required (),
639- mcp .Description ("Repository name" ),
640- ),
641- mcp .WithNumber ("issue_number" ,
642- mcp .Required (),
643- mcp .Description ("The number of the parent issue" ),
644- ),
645- mcp .WithNumber ("sub_issue_id" ,
646- mcp .Required (),
647- mcp .Description ("The ID of the sub-issue to add. ID is not the same as issue number" ),
648- ),
649- mcp .WithBoolean ("replace_parent" ,
650- mcp .Description ("When true, replaces the sub-issue's current parent issue. Use with 'add' method only." ),
651- ),
652- mcp .WithNumber ("after_id" ,
653- mcp .Description ("The ID of the sub-issue to be prioritized after (either after_id OR before_id should be specified)" ),
654- ),
655- mcp .WithNumber ("before_id" ,
656- mcp .Description ("The ID of the sub-issue to be prioritized before (either after_id OR before_id should be specified)" ),
657- ),
658- ),
659- func (ctx context.Context , request mcp.CallToolRequest ) (* mcp.CallToolResult , error ) {
660- method , err := RequiredParam [string ](request , "method" )
642+ ` ,
643+ },
644+ "owner" : {
645+ Type : "string" ,
646+ Description : "Repository owner" ,
647+ },
648+ "repo" : {
649+ Type : "string" ,
650+ Description : "Repository name" ,
651+ },
652+ "issue_number" : {
653+ Type : "number" ,
654+ Description : "The number of the parent issue" ,
655+ },
656+ "sub_issue_id" : {
657+ Type : "number" ,
658+ Description : "The ID of the sub-issue to add. ID is not the same as issue number" ,
659+ },
660+ "replace_parent" : {
661+ Type : "boolean" ,
662+ Description : "When true, replaces the sub-issue's current parent issue. Use with 'add' method only." ,
663+ },
664+ "after_id" : {
665+ Type : "number" ,
666+ Description : "The ID of the sub-issue to be prioritized after (either after_id OR before_id should be specified)" ,
667+ },
668+ "before_id" : {
669+ Type : "number" ,
670+ Description : "The ID of the sub-issue to be prioritized before (either after_id OR before_id should be specified)" ,
671+ },
672+ },
673+ Required : []string {"method" , "owner" , "repo" , "issue_number" , "sub_issue_id" },
674+ },
675+ },
676+ func (ctx context.Context , _ * mcp.CallToolRequest , args map [string ]any ) (* mcp.CallToolResult , any , error ) {
677+ method , err := RequiredParam [string ](args , "method" )
661678 if err != nil {
662- return mcp .NewToolResultError (err .Error ()), nil
679+ return utils .NewToolResultError (err .Error ()), nil , nil
663680 }
664681
665- owner , err := RequiredParam [string ](request , "owner" )
682+ owner , err := RequiredParam [string ](args , "owner" )
666683 if err != nil {
667- return mcp .NewToolResultError (err .Error ()), nil
684+ return utils .NewToolResultError (err .Error ()), nil , nil
668685 }
669- repo , err := RequiredParam [string ](request , "repo" )
686+ repo , err := RequiredParam [string ](args , "repo" )
670687 if err != nil {
671- return mcp .NewToolResultError (err .Error ()), nil
688+ return utils .NewToolResultError (err .Error ()), nil , nil
672689 }
673- issueNumber , err := RequiredInt (request , "issue_number" )
690+ issueNumber , err := RequiredInt (args , "issue_number" )
674691 if err != nil {
675- return mcp .NewToolResultError (err .Error ()), nil
692+ return utils .NewToolResultError (err .Error ()), nil , nil
676693 }
677- subIssueID , err := RequiredInt (request , "sub_issue_id" )
694+ subIssueID , err := RequiredInt (args , "sub_issue_id" )
678695 if err != nil {
679- return mcp .NewToolResultError (err .Error ()), nil
696+ return utils .NewToolResultError (err .Error ()), nil , nil
680697 }
681- replaceParent , err := OptionalParam [bool ](request , "replace_parent" )
698+ replaceParent , err := OptionalParam [bool ](args , "replace_parent" )
682699 if err != nil {
683- return mcp .NewToolResultError (err .Error ()), nil
700+ return utils .NewToolResultError (err .Error ()), nil , nil
684701 }
685- afterID , err := OptionalIntParam (request , "after_id" )
702+ afterID , err := OptionalIntParam (args , "after_id" )
686703 if err != nil {
687- return mcp .NewToolResultError (err .Error ()), nil
704+ return utils .NewToolResultError (err .Error ()), nil , nil
688705 }
689- beforeID , err := OptionalIntParam (request , "before_id" )
706+ beforeID , err := OptionalIntParam (args , "before_id" )
690707 if err != nil {
691- return mcp .NewToolResultError (err .Error ()), nil
708+ return utils .NewToolResultError (err .Error ()), nil , nil
692709 }
693710
694711 client , err := getClient (ctx )
695712 if err != nil {
696- return nil , fmt . Errorf ("failed to get GitHub client: %w " , err )
713+ return utils . NewToolResultErrorFromErr ("failed to get GitHub client" , err ), nil , nil
697714 }
698715
699716 switch strings .ToLower (method ) {
700717 case "add" :
701- return AddSubIssue (ctx , client , owner , repo , issueNumber , subIssueID , replaceParent )
718+ result , err := AddSubIssue (ctx , client , owner , repo , issueNumber , subIssueID , replaceParent )
719+ return result , nil , err
702720 case "remove" :
703721 // Call the remove sub-issue function
704- return RemoveSubIssue (ctx , client , owner , repo , issueNumber , subIssueID )
722+ result , err := RemoveSubIssue (ctx , client , owner , repo , issueNumber , subIssueID )
723+ return result , nil , err
705724 case "reprioritize" :
706725 // Call the reprioritize sub-issue function
707- return ReprioritizeSubIssue (ctx , client , owner , repo , issueNumber , subIssueID , afterID , beforeID )
726+ result , err := ReprioritizeSubIssue (ctx , client , owner , repo , issueNumber , subIssueID , afterID , beforeID )
727+ return result , nil , err
708728 default :
709- return mcp .NewToolResultError (fmt .Sprintf ("unknown method: %s" , method )), nil
729+ return utils .NewToolResultError (fmt .Sprintf ("unknown method: %s" , method )), nil , nil
710730 }
711731 }
712732}
@@ -733,15 +753,15 @@ func AddSubIssue(ctx context.Context, client *github.Client, owner string, repo
733753 if err != nil {
734754 return nil , fmt .Errorf ("failed to read response body: %w" , err )
735755 }
736- return mcp .NewToolResultError (fmt .Sprintf ("failed to add sub-issue: %s" , string (body ))), nil
756+ return utils .NewToolResultError (fmt .Sprintf ("failed to add sub-issue: %s" , string (body ))), nil
737757 }
738758
739759 r , err := json .Marshal (subIssue )
740760 if err != nil {
741761 return nil , fmt .Errorf ("failed to marshal response: %w" , err )
742762 }
743763
744- return mcp .NewToolResultText (string (r )), nil
764+ return utils .NewToolResultText (string (r )), nil
745765
746766}
747767
@@ -765,24 +785,24 @@ func RemoveSubIssue(ctx context.Context, client *github.Client, owner string, re
765785 if err != nil {
766786 return nil , fmt .Errorf ("failed to read response body: %w" , err )
767787 }
768- return mcp .NewToolResultError (fmt .Sprintf ("failed to remove sub-issue: %s" , string (body ))), nil
788+ return utils .NewToolResultError (fmt .Sprintf ("failed to remove sub-issue: %s" , string (body ))), nil
769789 }
770790
771791 r , err := json .Marshal (subIssue )
772792 if err != nil {
773793 return nil , fmt .Errorf ("failed to marshal response: %w" , err )
774794 }
775795
776- return mcp .NewToolResultText (string (r )), nil
796+ return utils .NewToolResultText (string (r )), nil
777797}
778798
779799func ReprioritizeSubIssue (ctx context.Context , client * github.Client , owner string , repo string , issueNumber int , subIssueID int , afterID int , beforeID int ) (* mcp.CallToolResult , error ) {
780800 // Validate that either after_id or before_id is specified, but not both
781801 if afterID == 0 && beforeID == 0 {
782- return mcp .NewToolResultError ("either after_id or before_id must be specified" ), nil
802+ return utils .NewToolResultError ("either after_id or before_id must be specified" ), nil
783803 }
784804 if afterID != 0 && beforeID != 0 {
785- return mcp .NewToolResultError ("only one of after_id or before_id should be specified, not both" ), nil
805+ return utils .NewToolResultError ("only one of after_id or before_id should be specified, not both" ), nil
786806 }
787807
788808 subIssueRequest := github.SubIssueRequest {
@@ -814,15 +834,15 @@ func ReprioritizeSubIssue(ctx context.Context, client *github.Client, owner stri
814834 if err != nil {
815835 return nil , fmt .Errorf ("failed to read response body: %w" , err )
816836 }
817- return mcp .NewToolResultError (fmt .Sprintf ("failed to reprioritize sub-issue: %s" , string (body ))), nil
837+ return utils .NewToolResultError (fmt .Sprintf ("failed to reprioritize sub-issue: %s" , string (body ))), nil
818838 }
819839
820840 r , err := json .Marshal (subIssue )
821841 if err != nil {
822842 return nil , fmt .Errorf ("failed to marshal response: %w" , err )
823843 }
824844
825- return mcp .NewToolResultText (string (r )), nil
845+ return utils .NewToolResultText (string (r )), nil
826846}
827847
828848// SearchIssues creates a tool to search for issues.
0 commit comments