Skip to content

Commit f14f0b3

Browse files
committed
Adding GetSecretScanningAlert and ListSecretScanningAlerts
1 parent ff3036d commit f14f0b3

File tree

3 files changed

+164
-0
lines changed

3 files changed

+164
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
.idea
22
cmd/github-mcp-server/github-mcp-server
3+
.vscode/mcp.json
34
# Added by goreleaser init:
45
dist/
56
__debug_bin*

pkg/github/secret_scanning.go

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
package github
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"fmt"
7+
"io"
8+
"net/http"
9+
10+
"github.com/github/github-mcp-server/pkg/translations"
11+
"github.com/google/go-github/v69/github"
12+
"github.com/mark3labs/mcp-go/mcp"
13+
"github.com/mark3labs/mcp-go/server"
14+
)
15+
16+
func GetSecretScanningAlert(getClient GetClientFn, t translations.TranslationHelperFunc) (tool mcp.Tool, handler server.ToolHandlerFunc) {
17+
return mcp.NewTool(
18+
"get_secret_scanning_alert",
19+
mcp.WithString("owner",
20+
mcp.Required(),
21+
mcp.Description("The owner of the repository."),
22+
),
23+
mcp.WithString("repo",
24+
mcp.Required(),
25+
mcp.Description("The name of the repository."),
26+
),
27+
mcp.WithNumber("alertNumber",
28+
mcp.Required(),
29+
mcp.Description("The number of the alert."),
30+
),
31+
),
32+
func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
33+
owner, err := requiredParam[string](request, "owner")
34+
if err != nil {
35+
return mcp.NewToolResultError(err.Error()), nil
36+
}
37+
repo, err := requiredParam[string](request, "repo")
38+
if err != nil {
39+
return mcp.NewToolResultError(err.Error()), nil
40+
}
41+
alertNumber, err := RequiredInt(request, "alertNumber")
42+
if err != nil {
43+
return mcp.NewToolResultError(err.Error()), nil
44+
}
45+
46+
client, err := getClient(ctx)
47+
if err != nil {
48+
return nil, fmt.Errorf("failed to get GitHub client: %w", err)
49+
}
50+
51+
alert, resp, err := client.SecretScanning.GetAlert(ctx, owner, repo, int64(alertNumber))
52+
if err != nil {
53+
return nil, fmt.Errorf("failed to get alert: %w", err)
54+
}
55+
defer func() { _ = resp.Body.Close() }()
56+
57+
if resp.StatusCode != http.StatusOK {
58+
body, err := io.ReadAll(resp.Body)
59+
if err != nil {
60+
return nil, fmt.Errorf("failed to read response body: %w", err)
61+
}
62+
return mcp.NewToolResultError(fmt.Sprintf("failed to get alert: %s", string(body))), nil
63+
}
64+
65+
r, err := json.Marshal(alert)
66+
if err != nil {
67+
return nil, fmt.Errorf("failed to marshal alert: %w", err)
68+
}
69+
70+
return mcp.NewToolResultText(string(r)), nil
71+
}
72+
}
73+
74+
func ListSecretScanningAlerts(getClient GetClientFn, t translations.TranslationHelperFunc) (tool mcp.Tool, handler server.ToolHandlerFunc) {
75+
return mcp.NewTool(
76+
"list_secret_scanning_alerts",
77+
mcp.WithString("owner",
78+
mcp.Required(),
79+
mcp.Description("The owner of the repository."),
80+
),
81+
mcp.WithString("repo",
82+
mcp.Required(),
83+
mcp.Description("The name of the repository."),
84+
),
85+
mcp.WithString("state",
86+
mcp.Description("Filter code scanning alerts by state ('open', 'resolved')"),
87+
mcp.Enum("open", "resolved"),
88+
),
89+
mcp.WithString("secret_type",
90+
mcp.Description("A comma-separated list of secret types to return. All default secret patterns are returned. To return generic patterns, pass the token name(s) in the parameter."),
91+
),
92+
mcp.WithString("resolution",
93+
mcp.Description("Filter code scanning alerts by resolution ('false_positive', 'wont_fix', 'revoked', 'pattern_edited', 'pattern_deleted', 'used_in_tests')"),
94+
mcp.Enum("false_positive", "wont_fix", "revoked", "pattern_edited", "pattern_deleted", "used_in_tests"),
95+
),
96+
mcp.WithString("sort",
97+
mcp.Description("Filter code scanning alerts by sort ('created', 'updated') Default: created"),
98+
mcp.DefaultString("created"),
99+
mcp.Enum("created", "updated"),
100+
),
101+
mcp.WithString("direction",
102+
mcp.Description("Filter code scanning alerts by direction ('desc', 'asc') Default: desc"),
103+
mcp.DefaultString("desc"),
104+
mcp.Enum("desc", "asc"),
105+
),
106+
),
107+
func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
108+
owner, err := requiredParam[string](request, "owner")
109+
if err != nil {
110+
return mcp.NewToolResultError(err.Error()), nil
111+
}
112+
repo, err := requiredParam[string](request, "repo")
113+
if err != nil {
114+
return mcp.NewToolResultError(err.Error()), nil
115+
}
116+
state, err := OptionalParam[string](request, "state")
117+
if err != nil {
118+
return mcp.NewToolResultError(err.Error()), nil
119+
}
120+
secretType, err := OptionalParam[string](request, "secret_type")
121+
if err != nil {
122+
return mcp.NewToolResultError(err.Error()), nil
123+
}
124+
resolution, err := OptionalParam[string](request, "resolution")
125+
if err != nil {
126+
return mcp.NewToolResultError(err.Error()), nil
127+
}
128+
sort, err := OptionalParam[string](request, "sort")
129+
if err != nil {
130+
return mcp.NewToolResultError(err.Error()), nil
131+
}
132+
direction, err := OptionalParam[string](request, "direction")
133+
if err != nil {
134+
return mcp.NewToolResultError(err.Error()), nil
135+
}
136+
137+
client, err := getClient(ctx)
138+
if err != nil {
139+
return nil, fmt.Errorf("failed to get GitHub client: %w", err)
140+
}
141+
alerts, resp, err := client.SecretScanning.ListAlertsForRepo(ctx, owner, repo, &github.SecretScanningAlertListOptions{State: state, SecretType: secretType, Resolution: resolution, Sort: sort, Direction: direction})
142+
if err != nil {
143+
return nil, fmt.Errorf("failed to list alerts: %w", err)
144+
}
145+
defer func() { _ = resp.Body.Close() }()
146+
147+
if resp.StatusCode != http.StatusOK {
148+
body, err := io.ReadAll(resp.Body)
149+
if err != nil {
150+
return nil, fmt.Errorf("failed to read response body: %w", err)
151+
}
152+
return mcp.NewToolResultError(fmt.Sprintf("failed to list alerts: %s", string(body))), nil
153+
}
154+
155+
r, err := json.Marshal(alerts)
156+
if err != nil {
157+
return nil, fmt.Errorf("failed to marshal alerts: %w", err)
158+
}
159+
160+
return mcp.NewToolResultText(string(r)), nil
161+
}
162+
}

pkg/github/secret_scanning_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
package github

0 commit comments

Comments
 (0)