@@ -182,6 +182,95 @@ func ListGlobalSecurityAdvisories(getClient GetClientFn, t translations.Translat
182
182
}
183
183
}
184
184
185
+ func ListRepositorySecurityAdvisories (getClient GetClientFn , t translations.TranslationHelperFunc ) (tool mcp.Tool , handler server.ToolHandlerFunc ) {
186
+ return mcp .NewTool ("list_repository_security_advisories" ,
187
+ mcp .WithDescription (t ("TOOL_LIST_REPOSITORY_SECURITY_ADVISORIES_DESCRIPTION" , "List repository security advisories for a GitHub repository." )),
188
+ mcp .WithToolAnnotation (mcp.ToolAnnotation {
189
+ Title : t ("TOOL_LIST_REPOSITORY_SECURITY_ADVISORIES_USER_TITLE" , "List repository security advisories" ),
190
+ ReadOnlyHint : ToBoolPtr (true ),
191
+ }),
192
+ mcp .WithString ("owner" ,
193
+ mcp .Required (),
194
+ mcp .Description ("The owner of the repository." ),
195
+ ),
196
+ mcp .WithString ("repo" ,
197
+ mcp .Required (),
198
+ mcp .Description ("The name of the repository." ),
199
+ ),
200
+ mcp .WithString ("direction" ,
201
+ mcp .Description ("Sort direction." ),
202
+ mcp .Enum ("asc" , "desc" ),
203
+ ),
204
+ mcp .WithString ("sort" ,
205
+ mcp .Description ("Sort field." ),
206
+ mcp .Enum ("created" , "updated" , "published" ),
207
+ ),
208
+ mcp .WithString ("state" ,
209
+ mcp .Description ("Filter by advisory state." ),
210
+ mcp .Enum ("triage" , "draft" , "published" , "closed" ),
211
+ ),
212
+ ), func (ctx context.Context , request mcp.CallToolRequest ) (* mcp.CallToolResult , error ) {
213
+ owner , err := RequiredParam [string ](request , "owner" )
214
+ if err != nil {
215
+ return mcp .NewToolResultError (err .Error ()), nil
216
+ }
217
+ repo , err := RequiredParam [string ](request , "repo" )
218
+ if err != nil {
219
+ return mcp .NewToolResultError (err .Error ()), nil
220
+ }
221
+
222
+ direction , err := OptionalParam [string ](request , "direction" )
223
+ if err != nil {
224
+ return mcp .NewToolResultError (err .Error ()), nil
225
+ }
226
+ sortField , err := OptionalParam [string ](request , "sort" )
227
+ if err != nil {
228
+ return mcp .NewToolResultError (err .Error ()), nil
229
+ }
230
+ state , err := OptionalParam [string ](request , "state" )
231
+ if err != nil {
232
+ return mcp .NewToolResultError (err .Error ()), nil
233
+ }
234
+
235
+ client , err := getClient (ctx )
236
+ if err != nil {
237
+ return nil , fmt .Errorf ("failed to get GitHub client: %w" , err )
238
+ }
239
+
240
+ opts := & github.ListRepositorySecurityAdvisoriesOptions {}
241
+ if direction != "" {
242
+ opts .Direction = direction
243
+ }
244
+ if sortField != "" {
245
+ opts .Sort = sortField
246
+ }
247
+ if state != "" {
248
+ opts .State = state
249
+ }
250
+
251
+ advisories , resp , err := client .SecurityAdvisories .ListRepositorySecurityAdvisories (ctx , owner , repo , opts )
252
+ if err != nil {
253
+ return nil , fmt .Errorf ("failed to list repository security advisories: %w" , err )
254
+ }
255
+ defer func () { _ = resp .Body .Close () }()
256
+
257
+ if resp .StatusCode != http .StatusOK {
258
+ body , err := io .ReadAll (resp .Body )
259
+ if err != nil {
260
+ return nil , fmt .Errorf ("failed to read response body: %w" , err )
261
+ }
262
+ return mcp .NewToolResultError (fmt .Sprintf ("failed to list repository advisories: %s" , string (body ))), nil
263
+ }
264
+
265
+ r , err := json .Marshal (advisories )
266
+ if err != nil {
267
+ return nil , fmt .Errorf ("failed to marshal advisories: %w" , err )
268
+ }
269
+
270
+ return mcp .NewToolResultText (string (r )), nil
271
+ }
272
+ }
273
+
185
274
func GetGlobalSecurityAdvisory (getClient GetClientFn , t translations.TranslationHelperFunc ) (tool mcp.Tool , handler server.ToolHandlerFunc ) {
186
275
return mcp .NewTool ("get_global_security_advisory" ,
187
276
mcp .WithDescription (t ("TOOL_GET_GLOBAL_SECURITY_ADVISORY_DESCRIPTION" , "Get a global security advisory" )),
@@ -226,3 +315,83 @@ func GetGlobalSecurityAdvisory(getClient GetClientFn, t translations.Translation
226
315
return mcp .NewToolResultText (string (r )), nil
227
316
}
228
317
}
318
+
319
+ func ListOrgRepositorySecurityAdvisories (getClient GetClientFn , t translations.TranslationHelperFunc ) (tool mcp.Tool , handler server.ToolHandlerFunc ) {
320
+ return mcp .NewTool ("list_org_repository_security_advisories" ,
321
+ mcp .WithDescription (t ("TOOL_LIST_ORG_REPOSITORY_SECURITY_ADVISORIES_DESCRIPTION" , "List repository security advisories for a GitHub organization." )),
322
+ mcp .WithToolAnnotation (mcp.ToolAnnotation {
323
+ Title : t ("TOOL_LIST_ORG_REPOSITORY_SECURITY_ADVISORIES_USER_TITLE" , "List org repository security advisories" ),
324
+ ReadOnlyHint : ToBoolPtr (true ),
325
+ }),
326
+ mcp .WithString ("org" ,
327
+ mcp .Required (),
328
+ mcp .Description ("The organization login." ),
329
+ ),
330
+ mcp .WithString ("direction" ,
331
+ mcp .Description ("Sort direction." ),
332
+ mcp .Enum ("asc" , "desc" ),
333
+ ),
334
+ mcp .WithString ("sort" ,
335
+ mcp .Description ("Sort field." ),
336
+ mcp .Enum ("created" , "updated" , "published" ),
337
+ ),
338
+ mcp .WithString ("state" ,
339
+ mcp .Description ("Filter by advisory state." ),
340
+ mcp .Enum ("triage" , "draft" , "published" , "closed" ),
341
+ ),
342
+ ), func (ctx context.Context , request mcp.CallToolRequest ) (* mcp.CallToolResult , error ) {
343
+ org , err := RequiredParam [string ](request , "org" )
344
+ if err != nil {
345
+ return mcp .NewToolResultError (err .Error ()), nil
346
+ }
347
+ direction , err := OptionalParam [string ](request , "direction" )
348
+ if err != nil {
349
+ return mcp .NewToolResultError (err .Error ()), nil
350
+ }
351
+ sortField , err := OptionalParam [string ](request , "sort" )
352
+ if err != nil {
353
+ return mcp .NewToolResultError (err .Error ()), nil
354
+ }
355
+ state , err := OptionalParam [string ](request , "state" )
356
+ if err != nil {
357
+ return mcp .NewToolResultError (err .Error ()), nil
358
+ }
359
+
360
+ client , err := getClient (ctx )
361
+ if err != nil {
362
+ return nil , fmt .Errorf ("failed to get GitHub client: %w" , err )
363
+ }
364
+
365
+ opts := & github.ListRepositorySecurityAdvisoriesOptions {}
366
+ if direction != "" {
367
+ opts .Direction = direction
368
+ }
369
+ if sortField != "" {
370
+ opts .Sort = sortField
371
+ }
372
+ if state != "" {
373
+ opts .State = state
374
+ }
375
+
376
+ advisories , resp , err := client .SecurityAdvisories .ListRepositorySecurityAdvisoriesForOrg (ctx , org , opts )
377
+ if err != nil {
378
+ return nil , fmt .Errorf ("failed to list organization repository security advisories: %w" , err )
379
+ }
380
+ defer func () { _ = resp .Body .Close () }()
381
+
382
+ if resp .StatusCode != http .StatusOK {
383
+ body , err := io .ReadAll (resp .Body )
384
+ if err != nil {
385
+ return nil , fmt .Errorf ("failed to read response body: %w" , err )
386
+ }
387
+ return mcp .NewToolResultError (fmt .Sprintf ("failed to list organization repository advisories: %s" , string (body ))), nil
388
+ }
389
+
390
+ r , err := json .Marshal (advisories )
391
+ if err != nil {
392
+ return nil , fmt .Errorf ("failed to marshal advisories: %w" , err )
393
+ }
394
+
395
+ return mcp .NewToolResultText (string (r )), nil
396
+ }
397
+ }
0 commit comments