@@ -160,104 +160,132 @@ type MinimalSearchUsersResult struct {
160160}
161161
162162// SearchUsers creates a tool to search for GitHub users.
163- func SearchUsers (getClient GetClientFn , t translations.TranslationHelperFunc ) (tool mcp.Tool , handler server.ToolHandlerFunc ) {
164- return mcp .NewTool ("search_users" ,
165- mcp .WithDescription (t ("TOOL_SEARCH_USERS_DESCRIPTION" , "Search for GitHub users" )),
166- mcp .WithToolAnnotation (mcp.ToolAnnotation {
167- Title : t ("TOOL_SEARCH_USERS_USER_TITLE" , "Search users" ),
168- ReadOnlyHint : toBoolPtr (true ),
169- }),
170- mcp .WithString ("q" ,
171- mcp .Required (),
172- mcp .Description ("Search query using GitHub users search syntax" ),
173- ),
174- mcp .WithString ("sort" ,
175- mcp .Description ("Sort field by category" ),
176- mcp .Enum ("followers" , "repositories" , "joined" ),
177- ),
178- mcp .WithString ("order" ,
179- mcp .Description ("Sort order" ),
180- mcp .Enum ("asc" , "desc" ),
181- ),
182- WithPagination (),
183- ),
184- func (ctx context.Context , request mcp.CallToolRequest ) (* mcp.CallToolResult , error ) {
185- query , err := requiredParam [string ](request , "q" )
186- if err != nil {
187- return mcp .NewToolResultError (err .Error ()), nil
188- }
189- sort , err := OptionalParam [string ](request , "sort" )
190- if err != nil {
191- return mcp .NewToolResultError (err .Error ()), nil
192- }
193- order , err := OptionalParam [string ](request , "order" )
194- if err != nil {
195- return mcp .NewToolResultError (err .Error ()), nil
196- }
197- pagination , err := OptionalPaginationParams (request )
198- if err != nil {
199- return mcp .NewToolResultError (err .Error ()), nil
200- }
163+ func userOrOrgHandler (accountType string , getClient GetClientFn ) server.ToolHandlerFunc {
164+ return func (ctx context.Context , request mcp.CallToolRequest ) (* mcp.CallToolResult , error ) {
165+ query , err := requiredParam [string ](request , "q" )
166+ if err != nil {
167+ return mcp .NewToolResultError (err .Error ()), nil
168+ }
169+ sort , err := OptionalParam [string ](request , "sort" )
170+ if err != nil {
171+ return mcp .NewToolResultError (err .Error ()), nil
172+ }
173+ order , err := OptionalParam [string ](request , "order" )
174+ if err != nil {
175+ return mcp .NewToolResultError (err .Error ()), nil
176+ }
177+ pagination , err := OptionalPaginationParams (request )
178+ if err != nil {
179+ return mcp .NewToolResultError (err .Error ()), nil
180+ }
201181
202- opts := & github.SearchOptions {
203- Sort : sort ,
204- Order : order ,
205- ListOptions : github.ListOptions {
206- PerPage : pagination .perPage ,
207- Page : pagination .page ,
208- },
209- }
182+ opts := & github.SearchOptions {
183+ Sort : sort ,
184+ Order : order ,
185+ ListOptions : github.ListOptions {
186+ PerPage : pagination .perPage ,
187+ Page : pagination .page ,
188+ },
189+ }
210190
211- client , err := getClient (ctx )
212- if err != nil {
213- return nil , fmt .Errorf ("failed to get GitHub client: %w" , err )
214- }
191+ client , err := getClient (ctx )
192+ if err != nil {
193+ return nil , fmt .Errorf ("failed to get GitHub client: %w" , err )
194+ }
215195
216- result , resp , err := client .Search .Users (ctx , "type:user " + query , opts )
196+ searchQuery := "type:" + accountType + " " + query
197+ result , resp , err := client .Search .Users (ctx , searchQuery , opts )
198+ if err != nil {
199+ return nil , fmt .Errorf ("failed to search %ss: %w" , accountType , err )
200+ }
201+ defer func () { _ = resp .Body .Close () }()
202+
203+ if resp .StatusCode != 200 {
204+ body , err := io .ReadAll (resp .Body )
217205 if err != nil {
218- return nil , fmt .Errorf ("failed to search users : %w" , err )
206+ return nil , fmt .Errorf ("failed to read response body : %w" , err )
219207 }
220- defer func () { _ = resp .Body .Close () }()
208+ return mcp .NewToolResultError (fmt .Sprintf ("failed to search %ss: %s" , accountType , string (body ))), nil
209+ }
221210
222- if resp .StatusCode != 200 {
223- body , err := io .ReadAll (resp .Body )
224- if err != nil {
225- return nil , fmt .Errorf ("failed to read response body: %w" , err )
211+ minimalUsers := make ([]MinimalUser , 0 , len (result .Users ))
212+ for _ , user := range result .Users {
213+ if user .Login != nil {
214+ mu := MinimalUser {Login : * user .Login }
215+ if user .ID != nil {
216+ mu .ID = * user .ID
226217 }
227- return mcp .NewToolResultError (fmt .Sprintf ("failed to search users: %s" , string (body ))), nil
228- }
229-
230- minimalUsers := make ([]MinimalUser , 0 , len (result .Users ))
231- for _ , user := range result .Users {
232- if user .Login != nil {
233- mu := MinimalUser {Login : * user .Login }
234- if user .ID != nil {
235- mu .ID = * user .ID
236- }
237- if user .HTMLURL != nil {
238- mu .ProfileURL = * user .HTMLURL
239- }
240- if user .AvatarURL != nil {
241- mu .AvatarURL = * user .AvatarURL
242- }
243- minimalUsers = append (minimalUsers , mu )
218+ if user .HTMLURL != nil {
219+ mu .ProfileURL = * user .HTMLURL
244220 }
221+ if user .AvatarURL != nil {
222+ mu .AvatarURL = * user .AvatarURL
223+ }
224+ minimalUsers = append (minimalUsers , mu )
245225 }
246- minimalResp := MinimalSearchUsersResult {
247- TotalCount : result .GetTotal (),
248- IncompleteResults : result .GetIncompleteResults (),
249- Items : minimalUsers ,
250- }
251- if result .Total != nil {
252- minimalResp .TotalCount = * result .Total
253- }
254- if result .IncompleteResults != nil {
255- minimalResp .IncompleteResults = * result .IncompleteResults
256- }
257- r , err := json .Marshal (minimalResp )
258- if err != nil {
259- return nil , fmt .Errorf ("failed to marshal response: %w" , err )
260- }
261- return mcp .NewToolResultText (string (r )), nil
262226 }
227+ minimalResp := & MinimalSearchUsersResult {
228+ TotalCount : result .GetTotal (),
229+ IncompleteResults : result .GetIncompleteResults (),
230+ Items : minimalUsers ,
231+ }
232+ if result .Total != nil {
233+ minimalResp .TotalCount = * result .Total
234+ }
235+ if result .IncompleteResults != nil {
236+ minimalResp .IncompleteResults = * result .IncompleteResults
237+ }
238+ r , err := json .Marshal (minimalResp )
239+ if err != nil {
240+ return nil , fmt .Errorf ("failed to marshal response: %w" , err )
241+ }
242+ return mcp .NewToolResultText (string (r )), nil
243+ }
244+ }
245+
246+ func SearchUsers (getClient GetClientFn , t translations.TranslationHelperFunc ) (tool mcp.Tool , handler server.ToolHandlerFunc ) {
247+ return mcp .NewTool ("search_users" ,
248+ mcp .WithDescription (t ("TOOL_SEARCH_USERS_DESCRIPTION" , "Search for GitHub users exlusively" )),
249+ mcp .WithToolAnnotation (mcp.ToolAnnotation {
250+ Title : t ("TOOL_SEARCH_USERS_USER_TITLE" , "Search users" ),
251+ ReadOnlyHint : toBoolPtr (true ),
252+ }),
253+ mcp .WithString ("q" ,
254+ mcp .Required (),
255+ mcp .Description ("Search query using GitHub users search syntax scoped to type:user" ),
256+ ),
257+ mcp .WithString ("sort" ,
258+ mcp .Description ("Sort field by category" ),
259+ mcp .Enum ("followers" , "repositories" , "joined" ),
260+ ),
261+ mcp .WithString ("order" ,
262+ mcp .Description ("Sort order" ),
263+ mcp .Enum ("asc" , "desc" ),
264+ ),
265+ WithPagination (),
266+ ), userOrOrgHandler ("user" , getClient )
267+ }
268+
269+ // SearchOrgs creates a tool to search for GitHub organizations.
270+ func SearchOrgs (getClient GetClientFn , t translations.TranslationHelperFunc ) (tool mcp.Tool , handler server.ToolHandlerFunc ) {
271+ return mcp .NewTool ("search_orgs" ,
272+ mcp .WithDescription (t ("TOOL_SEARCH_ORGS_DESCRIPTION" , "Search for GitHub organizations exclusively" )),
273+ mcp .WithToolAnnotation (mcp.ToolAnnotation {
274+ Title : t ("TOOL_SEARCH_ORGS_USER_TITLE" , "Search organizations" ),
275+ ReadOnlyHint : toBoolPtr (true ),
276+ }),
277+ mcp .WithString ("q" ,
278+ mcp .Required (),
279+ mcp .Description ("Search query using GitHub organizations search syntax scoped to type:org" ),
280+ ),
281+ mcp .WithString ("sort" ,
282+ mcp .Description ("Sort field by category" ),
283+ mcp .Enum ("followers" , "repositories" , "joined" ),
284+ ),
285+ mcp .WithString ("order" ,
286+ mcp .Description ("Sort order" ),
287+ mcp .Enum ("asc" , "desc" ),
288+ ),
289+ WithPagination (),
290+ ), userOrOrgHandler ("org" , getClient )
263291}
0 commit comments