diff --git a/README.md b/README.md index 8cff2e138..0b610bead 100644 --- a/README.md +++ b/README.md @@ -900,7 +900,7 @@ export GITHUB_MCP_TOOL_ADD_ISSUE_COMMENT_DESCRIPTION="an alternative description - **get_file_contents** - Get file or directory contents - `owner`: Repository owner (username or organization) (string, required) - `path`: Path to file/directory (directories must end with a slash '/') (string, required) - - `ref`: Accepts optional git refs such as `refs/tags/{tag}`, `refs/heads/{branch}` or `refs/pull/{pr_number}/head` (string, optional) + - `ref`: Accepts optional git refs such as `refs/tags/{tag}`, `refs/heads/{branch}` or `refs/pull/{pr_number}/head` (string, optional). For example, use `refs/pull/123/head` to fetch content from a pull request head. - `repo`: Repository name (string, required) - `sha`: Accepts optional commit SHA. If specified, it will be used instead of ref (string, optional) diff --git a/pkg/github/repositories_test.go b/pkg/github/repositories_test.go index b621cec43..8cc0dec0d 100644 --- a/pkg/github/repositories_test.go +++ b/pkg/github/repositories_test.go @@ -167,6 +167,37 @@ func Test_GetFileContents(t *testing.T) { expectError: false, expectedResult: mcp.NewToolResultError("Failed to get file contents. The path does not point to a file or directory, or the file does not exist in the repository."), }, + { + name: "successful PR head content fetch", + mockedClient: mock.NewMockedHTTPClient( + mock.WithRequestMatchHandler( + mock.GetReposPullsByOwnerByRepoByPullNumber, + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + w.Header().Set("Content-Type", "application/json") + _, _ = w.Write([]byte(`{"head":{"sha":"prsha"}}`)) + }), + ), + mock.WithRequestMatchHandler( + raw.GetRawReposContentsByOwnerByRepoBySHAByPath, + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + w.Header().Set("Content-Type", "text/plain") + _, _ = w.Write([]byte("PR content")) + }), + ), + ), + requestArgs: map[string]interface{}{ + "owner": "owner", + "repo": "repo", + "path": "file.txt", + "ref": "refs/pull/5/head", + }, + expectError: false, + expectedResult: mcp.TextResourceContents{ + URI: "repo://owner/repo/sha/prsha/contents/file.txt", + Text: "PR content", + MIMEType: "text/plain", + }, + }, } for _, tc := range tests { diff --git a/pkg/github/repository_resource_test.go b/pkg/github/repository_resource_test.go index 0e9f018e7..159791ef6 100644 --- a/pkg/github/repository_resource_test.go +++ b/pkg/github/repository_resource_test.go @@ -278,3 +278,9 @@ func Test_GetRepositoryResourceTagContent(t *testing.T) { tmpl, _ := GetRepositoryResourceTagContent(nil, stubGetRawClientFn(mockRawClient), translations.NullTranslationHelper) require.Equal(t, "repo://{owner}/{repo}/refs/tags/{tag}/contents{/path*}", tmpl.URITemplate.Raw()) } + +func Test_GetRepositoryResourcePrContent(t *testing.T) { + mockRawClient := raw.NewClient(github.NewClient(nil), &url.URL{}) + tmpl, _ := GetRepositoryResourcePrContent(nil, stubGetRawClientFn(mockRawClient), translations.NullTranslationHelper) + require.Equal(t, "repo://{owner}/{repo}/refs/pull/{prNumber}/head/contents{/path*}", tmpl.URITemplate.Raw()) +}