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