diff --git a/pkg/github/search.go b/pkg/github/search.go index 2df39bcd8..8b5e83960 100644 --- a/pkg/github/search.go +++ b/pkg/github/search.go @@ -146,6 +146,19 @@ func SearchCode(getClient GetClientFn, t translations.TranslationHelperFunc) (to } } +type MinimalUser struct { + Login string `json:"login"` + ID int64 `json:"id,omitempty"` + ProfileURL string `json:"profile_url,omitempty"` + AvatarURL string `json:"avatar_url,omitempty"` +} + +type MinimalSearchUsersResult struct { + TotalCount int `json:"total_count"` + IncompleteResults bool `json:"incomplete_results"` + Items []MinimalUser `json:"items"` +} + // SearchUsers creates a tool to search for GitHub users. func SearchUsers(getClient GetClientFn, t translations.TranslationHelperFunc) (tool mcp.Tool, handler server.ToolHandlerFunc) { return mcp.NewTool("search_users", @@ -200,7 +213,7 @@ func SearchUsers(getClient GetClientFn, t translations.TranslationHelperFunc) (t return nil, fmt.Errorf("failed to get GitHub client: %w", err) } - result, resp, err := client.Search.Users(ctx, query, opts) + result, resp, err := client.Search.Users(ctx, "type:user "+query, opts) if err != nil { return nil, fmt.Errorf("failed to search users: %w", err) } @@ -214,11 +227,28 @@ func SearchUsers(getClient GetClientFn, t translations.TranslationHelperFunc) (t return mcp.NewToolResultError(fmt.Sprintf("failed to search users: %s", string(body))), nil } - r, err := json.Marshal(result) + minimalUsers := make([]MinimalUser, 0, len(result.Users)) + for _, user := range result.Users { + mu := MinimalUser{ + Login: user.GetLogin(), + ID: user.GetID(), + ProfileURL: user.GetHTMLURL(), + AvatarURL: user.GetAvatarURL(), + } + + minimalUsers = append(minimalUsers, mu) + } + + minimalResp := MinimalSearchUsersResult{ + TotalCount: result.GetTotal(), + IncompleteResults: result.GetIncompleteResults(), + Items: minimalUsers, + } + + r, err := json.Marshal(minimalResp) if err != nil { return nil, fmt.Errorf("failed to marshal response: %w", err) } - return mcp.NewToolResultText(string(r)), nil } } diff --git a/pkg/github/search_test.go b/pkg/github/search_test.go index 3cd858de0..62645e91d 100644 --- a/pkg/github/search_test.go +++ b/pkg/github/search_test.go @@ -335,9 +335,6 @@ func Test_SearchUsers(t *testing.T) { ID: github.Ptr(int64(1001)), HTMLURL: github.Ptr("https://github.com/user1"), AvatarURL: github.Ptr("https://avatars.githubusercontent.com/u/1001"), - Type: github.Ptr("User"), - Followers: github.Ptr(100), - Following: github.Ptr(50), }, { Login: github.Ptr("user2"), @@ -345,8 +342,6 @@ func Test_SearchUsers(t *testing.T) { HTMLURL: github.Ptr("https://github.com/user2"), AvatarURL: github.Ptr("https://avatars.githubusercontent.com/u/1002"), Type: github.Ptr("User"), - Followers: github.Ptr(200), - Following: github.Ptr(75), }, }, } @@ -365,7 +360,7 @@ func Test_SearchUsers(t *testing.T) { mock.WithRequestMatchHandler( mock.GetSearchUsers, expectQueryParams(t, map[string]string{ - "q": "location:finland language:go", + "q": "type:user location:finland language:go", "sort": "followers", "order": "desc", "page": "1", @@ -391,7 +386,7 @@ func Test_SearchUsers(t *testing.T) { mock.WithRequestMatchHandler( mock.GetSearchUsers, expectQueryParams(t, map[string]string{ - "q": "location:finland language:go", + "q": "type:user location:finland language:go", "page": "1", "per_page": "30", }).andThen( @@ -451,19 +446,17 @@ func Test_SearchUsers(t *testing.T) { textContent := getTextResult(t, result) // Unmarshal and verify the result - var returnedResult github.UsersSearchResult + var returnedResult MinimalSearchUsersResult err = json.Unmarshal([]byte(textContent.Text), &returnedResult) require.NoError(t, err) - assert.Equal(t, *tc.expectedResult.Total, *returnedResult.Total) - assert.Equal(t, *tc.expectedResult.IncompleteResults, *returnedResult.IncompleteResults) - assert.Len(t, returnedResult.Users, len(tc.expectedResult.Users)) - for i, user := range returnedResult.Users { - assert.Equal(t, *tc.expectedResult.Users[i].Login, *user.Login) - assert.Equal(t, *tc.expectedResult.Users[i].ID, *user.ID) - assert.Equal(t, *tc.expectedResult.Users[i].HTMLURL, *user.HTMLURL) - assert.Equal(t, *tc.expectedResult.Users[i].AvatarURL, *user.AvatarURL) - assert.Equal(t, *tc.expectedResult.Users[i].Type, *user.Type) - assert.Equal(t, *tc.expectedResult.Users[i].Followers, *user.Followers) + assert.Equal(t, *tc.expectedResult.Total, returnedResult.TotalCount) + assert.Equal(t, *tc.expectedResult.IncompleteResults, returnedResult.IncompleteResults) + assert.Len(t, returnedResult.Items, len(tc.expectedResult.Users)) + for i, user := range returnedResult.Items { + assert.Equal(t, *tc.expectedResult.Users[i].Login, user.Login) + assert.Equal(t, *tc.expectedResult.Users[i].ID, user.ID) + assert.Equal(t, *tc.expectedResult.Users[i].HTMLURL, user.ProfileURL) + assert.Equal(t, *tc.expectedResult.Users[i].AvatarURL, user.AvatarURL) } }) }