@@ -14,6 +14,166 @@ import (
1414 "github.com/mark3labs/mcp-go/server"
1515)
1616
17+ // ManageCodeScanningAlerts creates a consolidated tool to perform operations on code scanning alerts
18+ func ManageCodeScanningAlerts (getClient GetClientFn , t translations.TranslationHelperFunc ) (tool mcp.Tool , handler server.ToolHandlerFunc ) {
19+ return mcp .NewTool ("manage_code_scanning_alerts" ,
20+ mcp .WithDescription (t ("TOOL_MANAGE_CODE_SCANNING_ALERTS_DESCRIPTION" , "Manage code scanning alerts with various operations: list, get" )),
21+ mcp .WithToolAnnotation (mcp.ToolAnnotation {
22+ Title : t ("TOOL_MANAGE_CODE_SCANNING_ALERTS" , "Manage Code Scanning Alerts" ),
23+ ReadOnlyHint : ToBoolPtr (true ),
24+ }),
25+ mcp .WithString ("operation" ,
26+ mcp .Required (),
27+ mcp .Description ("Operation to perform: 'list', 'get'" ),
28+ mcp .Enum ("list" , "get" ),
29+ ),
30+ mcp .WithString ("owner" ,
31+ mcp .Required (),
32+ mcp .Description ("The owner of the repository" ),
33+ ),
34+ mcp .WithString ("repo" ,
35+ mcp .Required (),
36+ mcp .Description ("The name of the repository" ),
37+ ),
38+ // Parameters for get operation
39+ mcp .WithNumber ("alertNumber" ,
40+ mcp .Description ("The number of the alert (required for 'get' operation)" ),
41+ ),
42+ // Parameters for list operation
43+ mcp .WithString ("state" ,
44+ mcp .Description ("Filter code scanning alerts by state (used for 'list' operation)" ),
45+ mcp .DefaultString ("open" ),
46+ mcp .Enum ("open" , "closed" , "dismissed" , "fixed" ),
47+ ),
48+ mcp .WithString ("ref" ,
49+ mcp .Description ("The Git reference for the results you want to list (used for 'list' operation)" ),
50+ ),
51+ mcp .WithString ("severity" ,
52+ mcp .Description ("Filter code scanning alerts by severity (used for 'list' operation)" ),
53+ mcp .Enum ("critical" , "high" , "medium" , "low" , "warning" , "note" , "error" ),
54+ ),
55+ mcp .WithString ("tool_name" ,
56+ mcp .Description ("The name of the tool used for code scanning (used for 'list' operation)" ),
57+ ),
58+ ),
59+ func (ctx context.Context , request mcp.CallToolRequest ) (* mcp.CallToolResult , error ) {
60+ operation , err := RequiredParam [string ](request , "operation" )
61+ if err != nil {
62+ return mcp .NewToolResultError (err .Error ()), nil
63+ }
64+
65+ switch operation {
66+ case "list" :
67+ return handleListCodeScanningAlerts (ctx , getClient , request )
68+ case "get" :
69+ return handleGetCodeScanningAlert (ctx , getClient , request )
70+ default :
71+ return mcp .NewToolResultError (fmt .Sprintf ("unsupported operation: %s" , operation )), nil
72+ }
73+ }
74+ }
75+
76+ func handleGetCodeScanningAlert (ctx context.Context , getClient GetClientFn , request mcp.CallToolRequest ) (* mcp.CallToolResult , error ) {
77+ owner , err := RequiredParam [string ](request , "owner" )
78+ if err != nil {
79+ return mcp .NewToolResultError (err .Error ()), nil
80+ }
81+ repo , err := RequiredParam [string ](request , "repo" )
82+ if err != nil {
83+ return mcp .NewToolResultError (err .Error ()), nil
84+ }
85+ alertNumber , err := RequiredInt (request , "alertNumber" )
86+ if err != nil {
87+ return mcp .NewToolResultError (err .Error ()), nil
88+ }
89+
90+ client , err := getClient (ctx )
91+ if err != nil {
92+ return nil , fmt .Errorf ("failed to get GitHub client: %w" , err )
93+ }
94+
95+ alert , resp , err := client .CodeScanning .GetAlert (ctx , owner , repo , int64 (alertNumber ))
96+ if err != nil {
97+ return ghErrors .NewGitHubAPIErrorResponse (ctx ,
98+ "failed to get alert" ,
99+ resp ,
100+ err ,
101+ ), nil
102+ }
103+ defer func () { _ = resp .Body .Close () }()
104+
105+ if resp .StatusCode != http .StatusOK {
106+ body , err := io .ReadAll (resp .Body )
107+ if err != nil {
108+ return nil , fmt .Errorf ("failed to read response body: %w" , err )
109+ }
110+ return mcp .NewToolResultError (fmt .Sprintf ("failed to get alert: %s" , string (body ))), nil
111+ }
112+
113+ r , err := json .Marshal (alert )
114+ if err != nil {
115+ return nil , fmt .Errorf ("failed to marshal alert: %w" , err )
116+ }
117+
118+ return mcp .NewToolResultText (string (r )), nil
119+ }
120+
121+ func handleListCodeScanningAlerts (ctx context.Context , getClient GetClientFn , request mcp.CallToolRequest ) (* mcp.CallToolResult , error ) {
122+ owner , err := RequiredParam [string ](request , "owner" )
123+ if err != nil {
124+ return mcp .NewToolResultError (err .Error ()), nil
125+ }
126+ repo , err := RequiredParam [string ](request , "repo" )
127+ if err != nil {
128+ return mcp .NewToolResultError (err .Error ()), nil
129+ }
130+ ref , err := OptionalParam [string ](request , "ref" )
131+ if err != nil {
132+ return mcp .NewToolResultError (err .Error ()), nil
133+ }
134+ state , err := OptionalParam [string ](request , "state" )
135+ if err != nil {
136+ return mcp .NewToolResultError (err .Error ()), nil
137+ }
138+ severity , err := OptionalParam [string ](request , "severity" )
139+ if err != nil {
140+ return mcp .NewToolResultError (err .Error ()), nil
141+ }
142+ toolName , err := OptionalParam [string ](request , "tool_name" )
143+ if err != nil {
144+ return mcp .NewToolResultError (err .Error ()), nil
145+ }
146+
147+ client , err := getClient (ctx )
148+ if err != nil {
149+ return nil , fmt .Errorf ("failed to get GitHub client: %w" , err )
150+ }
151+ alerts , resp , err := client .CodeScanning .ListAlertsForRepo (ctx , owner , repo , & github.AlertListOptions {Ref : ref , State : state , Severity : severity , ToolName : toolName })
152+ if err != nil {
153+ return ghErrors .NewGitHubAPIErrorResponse (ctx ,
154+ "failed to list alerts" ,
155+ resp ,
156+ err ,
157+ ), nil
158+ }
159+ defer func () { _ = resp .Body .Close () }()
160+
161+ if resp .StatusCode != http .StatusOK {
162+ body , err := io .ReadAll (resp .Body )
163+ if err != nil {
164+ return nil , fmt .Errorf ("failed to read response body: %w" , err )
165+ }
166+ return mcp .NewToolResultError (fmt .Sprintf ("failed to list alerts: %s" , string (body ))), nil
167+ }
168+
169+ r , err := json .Marshal (alerts )
170+ if err != nil {
171+ return nil , fmt .Errorf ("failed to marshal alerts: %w" , err )
172+ }
173+
174+ return mcp .NewToolResultText (string (r )), nil
175+ }
176+
17177func GetCodeScanningAlert (getClient GetClientFn , t translations.TranslationHelperFunc ) (tool mcp.Tool , handler server.ToolHandlerFunc ) {
18178 return mcp .NewTool ("get_code_scanning_alert" ,
19179 mcp .WithDescription (t ("TOOL_GET_CODE_SCANNING_ALERT_DESCRIPTION" , "Get details of a specific code scanning alert in a GitHub repository." )),
0 commit comments