Skip to content

Commit 6fd0bb9

Browse files
ashwin-antclaude
andcommitted
Add line parameter support to create_pull_request_review tool
- Updated schema to make path and body the only required fields - Added line parameter as alternative to position for inline comments - Updated handler to accept either position or line based on GitHub API spec - Added new test case that verifies line parameter works properly - Updated error messages for better validation 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 270bbf7 commit 6fd0bb9

File tree

3 files changed

+68
-17
lines changed

3 files changed

+68
-17
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ export GITHUB_MCP_TOOL_ADD_ISSUE_COMMENT_DESCRIPTION="an alternative description
266266
- `body`: Review comment text (string, optional)
267267
- `event`: Review action ('APPROVE', 'REQUEST_CHANGES', 'COMMENT') (string, required)
268268
- `commitId`: SHA of commit to review (string, optional)
269-
- `comments`: Line-specific comments array of objects, each object with path (string), position (number), and body (string) (array, optional)
269+
- `comments`: Line-specific comments array of objects, each object with path (string), either position (number) or line (number), and body (string) (array, optional)
270270

271271
- **create_pull_request** - Create a new pull request
272272

pkg/github/pullrequests.go

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -593,15 +593,19 @@ func createPullRequestReview(client *github.Client, t translations.TranslationHe
593593
map[string]interface{}{
594594
"type": "object",
595595
"additionalProperties": false,
596-
"required": []string{"path", "position", "body"},
596+
"required": []string{"path", "body"},
597597
"properties": map[string]interface{}{
598598
"path": map[string]interface{}{
599599
"type": "string",
600600
"description": "path to the file",
601601
},
602602
"position": map[string]interface{}{
603603
"type": "number",
604-
"description": "line number in the file",
604+
"description": "position of the comment in the diff",
605+
},
606+
"line": map[string]interface{}{
607+
"type": "number",
608+
"description": "line number in the file to comment on (alternative to position)",
605609
},
606610
"body": map[string]interface{}{
607611
"type": "string",
@@ -610,7 +614,7 @@ func createPullRequestReview(client *github.Client, t translations.TranslationHe
610614
},
611615
},
612616
),
613-
mcp.Description("Line-specific comments array of objects, each object with path (string), position (number), and body (string)"),
617+
mcp.Description("Line-specific comments array of objects, each object with path (string), either position (number) or line (number), and body (string)"),
614618
),
615619
),
616620
func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
@@ -661,30 +665,40 @@ func createPullRequestReview(client *github.Client, t translations.TranslationHe
661665
for _, c := range commentsObj {
662666
commentMap, ok := c.(map[string]interface{})
663667
if !ok {
664-
return mcp.NewToolResultError("each comment must be an object with path, position, and body"), nil
668+
return mcp.NewToolResultError("each comment must be an object with path and body"), nil
665669
}
666670

667671
path, ok := commentMap["path"].(string)
668672
if !ok || path == "" {
669673
return mcp.NewToolResultError("each comment must have a path"), nil
670674
}
671675

672-
positionFloat, ok := commentMap["position"].(float64)
673-
if !ok {
674-
return mcp.NewToolResultError("each comment must have a position"), nil
675-
}
676-
position := int(positionFloat)
677-
678676
body, ok := commentMap["body"].(string)
679677
if !ok || body == "" {
680678
return mcp.NewToolResultError("each comment must have a body"), nil
681679
}
682680

683-
comments = append(comments, &github.DraftReviewComment{
684-
Path: github.Ptr(path),
685-
Position: github.Ptr(position),
686-
Body: github.Ptr(body),
687-
})
681+
comment := &github.DraftReviewComment{
682+
Path: github.Ptr(path),
683+
Body: github.Ptr(body),
684+
}
685+
686+
// Check if position is provided
687+
if positionFloat, ok := commentMap["position"].(float64); ok {
688+
comment.Position = github.Ptr(int(positionFloat))
689+
}
690+
691+
// Check if line is provided
692+
if lineFloat, ok := commentMap["line"].(float64); ok {
693+
comment.Line = github.Ptr(int(lineFloat))
694+
}
695+
696+
// Ensure one of position or line is provided
697+
if comment.Position == nil && comment.Line == nil {
698+
return mcp.NewToolResultError("each comment must have either position or line"), nil
699+
}
700+
701+
comments = append(comments, comment)
688702
}
689703

690704
reviewRequest.Comments = comments

pkg/github/pullrequests_test.go

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1167,7 +1167,44 @@ func Test_CreatePullRequestReview(t *testing.T) {
11671167
},
11681168
},
11691169
expectError: false,
1170-
expectedErrMsg: "each comment must have a position",
1170+
expectedErrMsg: "each comment must have either position or line",
1171+
},
1172+
{
1173+
name: "successful review creation with line parameter",
1174+
mockedClient: mock.NewMockedHTTPClient(
1175+
mock.WithRequestMatchHandler(
1176+
mock.PostReposPullsReviewsByOwnerByRepoByPullNumber,
1177+
expectRequestBody(t, map[string]interface{}{
1178+
"body": "Code review comments",
1179+
"event": "COMMENT",
1180+
"comments": []interface{}{
1181+
map[string]interface{}{
1182+
"path": "main.go",
1183+
"line": float64(42),
1184+
"body": "Consider adding a comment here",
1185+
},
1186+
},
1187+
}).andThen(
1188+
mockResponse(t, http.StatusOK, mockReview),
1189+
),
1190+
),
1191+
),
1192+
requestArgs: map[string]interface{}{
1193+
"owner": "owner",
1194+
"repo": "repo",
1195+
"pullNumber": float64(42),
1196+
"body": "Code review comments",
1197+
"event": "COMMENT",
1198+
"comments": []interface{}{
1199+
map[string]interface{}{
1200+
"path": "main.go",
1201+
"line": float64(42),
1202+
"body": "Consider adding a comment here",
1203+
},
1204+
},
1205+
},
1206+
expectError: false,
1207+
expectedReview: mockReview,
11711208
},
11721209
{
11731210
name: "review creation fails",

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy