Skip to content

Commit 7988cb0

Browse files
Copilotomgitsads
andcommitted
Migrate dependabot toolset to modelcontextprotocol/go-sdk
Co-authored-by: omgitsads <[email protected]>
1 parent 5144f55 commit 7988cb0

File tree

2 files changed

+438
-412
lines changed

2 files changed

+438
-412
lines changed

pkg/github/dependabot.go

Lines changed: 180 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -1,161 +1,182 @@
11
package github
22

3-
// import (
4-
// "context"
5-
// "encoding/json"
6-
// "fmt"
7-
// "io"
8-
// "net/http"
9-
10-
// ghErrors "github.com/github/github-mcp-server/pkg/errors"
11-
// "github.com/github/github-mcp-server/pkg/translations"
12-
// "github.com/google/go-github/v77/github"
13-
// "github.com/mark3labs/mcp-go/mcp"
14-
// "github.com/mark3labs/mcp-go/server"
15-
// )
16-
17-
// func GetDependabotAlert(getClient GetClientFn, t translations.TranslationHelperFunc) (tool mcp.Tool, handler server.ToolHandlerFunc) {
18-
// return mcp.NewTool(
19-
// "get_dependabot_alert",
20-
// mcp.WithDescription(t("TOOL_GET_DEPENDABOT_ALERT_DESCRIPTION", "Get details of a specific dependabot alert in a GitHub repository.")),
21-
// mcp.WithToolAnnotation(mcp.ToolAnnotation{
22-
// Title: t("TOOL_GET_DEPENDABOT_ALERT_USER_TITLE", "Get dependabot alert"),
23-
// ReadOnlyHint: ToBoolPtr(true),
24-
// }),
25-
// mcp.WithString("owner",
26-
// mcp.Required(),
27-
// mcp.Description("The owner of the repository."),
28-
// ),
29-
// mcp.WithString("repo",
30-
// mcp.Required(),
31-
// mcp.Description("The name of the repository."),
32-
// ),
33-
// mcp.WithNumber("alertNumber",
34-
// mcp.Required(),
35-
// mcp.Description("The number of the alert."),
36-
// ),
37-
// ),
38-
// func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
39-
// owner, err := RequiredParam[string](request, "owner")
40-
// if err != nil {
41-
// return mcp.NewToolResultError(err.Error()), nil
42-
// }
43-
// repo, err := RequiredParam[string](request, "repo")
44-
// if err != nil {
45-
// return mcp.NewToolResultError(err.Error()), nil
46-
// }
47-
// alertNumber, err := RequiredInt(request, "alertNumber")
48-
// if err != nil {
49-
// return mcp.NewToolResultError(err.Error()), nil
50-
// }
51-
52-
// client, err := getClient(ctx)
53-
// if err != nil {
54-
// return nil, fmt.Errorf("failed to get GitHub client: %w", err)
55-
// }
56-
57-
// alert, resp, err := client.Dependabot.GetRepoAlert(ctx, owner, repo, alertNumber)
58-
// if err != nil {
59-
// return ghErrors.NewGitHubAPIErrorResponse(ctx,
60-
// fmt.Sprintf("failed to get alert with number '%d'", alertNumber),
61-
// resp,
62-
// err,
63-
// ), nil
64-
// }
65-
// defer func() { _ = resp.Body.Close() }()
66-
67-
// if resp.StatusCode != http.StatusOK {
68-
// body, err := io.ReadAll(resp.Body)
69-
// if err != nil {
70-
// return nil, fmt.Errorf("failed to read response body: %w", err)
71-
// }
72-
// return mcp.NewToolResultError(fmt.Sprintf("failed to get alert: %s", string(body))), nil
73-
// }
74-
75-
// r, err := json.Marshal(alert)
76-
// if err != nil {
77-
// return nil, fmt.Errorf("failed to marshal alert: %w", err)
78-
// }
79-
80-
// return mcp.NewToolResultText(string(r)), nil
81-
// }
82-
// }
83-
84-
// func ListDependabotAlerts(getClient GetClientFn, t translations.TranslationHelperFunc) (tool mcp.Tool, handler server.ToolHandlerFunc) {
85-
// return mcp.NewTool(
86-
// "list_dependabot_alerts",
87-
// mcp.WithDescription(t("TOOL_LIST_DEPENDABOT_ALERTS_DESCRIPTION", "List dependabot alerts in a GitHub repository.")),
88-
// mcp.WithToolAnnotation(mcp.ToolAnnotation{
89-
// Title: t("TOOL_LIST_DEPENDABOT_ALERTS_USER_TITLE", "List dependabot alerts"),
90-
// ReadOnlyHint: ToBoolPtr(true),
91-
// }),
92-
// mcp.WithString("owner",
93-
// mcp.Required(),
94-
// mcp.Description("The owner of the repository."),
95-
// ),
96-
// mcp.WithString("repo",
97-
// mcp.Required(),
98-
// mcp.Description("The name of the repository."),
99-
// ),
100-
// mcp.WithString("state",
101-
// mcp.Description("Filter dependabot alerts by state. Defaults to open"),
102-
// mcp.DefaultString("open"),
103-
// mcp.Enum("open", "fixed", "dismissed", "auto_dismissed"),
104-
// ),
105-
// mcp.WithString("severity",
106-
// mcp.Description("Filter dependabot alerts by severity"),
107-
// mcp.Enum("low", "medium", "high", "critical"),
108-
// ),
109-
// ),
110-
// func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
111-
// owner, err := RequiredParam[string](request, "owner")
112-
// if err != nil {
113-
// return mcp.NewToolResultError(err.Error()), nil
114-
// }
115-
// repo, err := RequiredParam[string](request, "repo")
116-
// if err != nil {
117-
// return mcp.NewToolResultError(err.Error()), nil
118-
// }
119-
// state, err := OptionalParam[string](request, "state")
120-
// if err != nil {
121-
// return mcp.NewToolResultError(err.Error()), nil
122-
// }
123-
// severity, err := OptionalParam[string](request, "severity")
124-
// if err != nil {
125-
// return mcp.NewToolResultError(err.Error()), nil
126-
// }
127-
128-
// client, err := getClient(ctx)
129-
// if err != nil {
130-
// return nil, fmt.Errorf("failed to get GitHub client: %w", err)
131-
// }
132-
133-
// alerts, resp, err := client.Dependabot.ListRepoAlerts(ctx, owner, repo, &github.ListAlertsOptions{
134-
// State: ToStringPtr(state),
135-
// Severity: ToStringPtr(severity),
136-
// })
137-
// if err != nil {
138-
// return ghErrors.NewGitHubAPIErrorResponse(ctx,
139-
// fmt.Sprintf("failed to list alerts for repository '%s/%s'", owner, repo),
140-
// resp,
141-
// err,
142-
// ), nil
143-
// }
144-
// defer func() { _ = resp.Body.Close() }()
145-
146-
// if resp.StatusCode != http.StatusOK {
147-
// body, err := io.ReadAll(resp.Body)
148-
// if err != nil {
149-
// return nil, fmt.Errorf("failed to read response body: %w", err)
150-
// }
151-
// return mcp.NewToolResultError(fmt.Sprintf("failed to list alerts: %s", string(body))), nil
152-
// }
153-
154-
// r, err := json.Marshal(alerts)
155-
// if err != nil {
156-
// return nil, fmt.Errorf("failed to marshal alerts: %w", err)
157-
// }
158-
159-
// return mcp.NewToolResultText(string(r)), nil
160-
// }
161-
// }
3+
import (
4+
"context"
5+
"encoding/json"
6+
"fmt"
7+
"io"
8+
"net/http"
9+
10+
ghErrors "github.com/github/github-mcp-server/pkg/errors"
11+
"github.com/github/github-mcp-server/pkg/translations"
12+
"github.com/github/github-mcp-server/pkg/utils"
13+
"github.com/google/go-github/v77/github"
14+
"github.com/google/jsonschema-go/jsonschema"
15+
"github.com/modelcontextprotocol/go-sdk/mcp"
16+
)
17+
18+
func GetDependabotAlert(getClient GetClientFn, t translations.TranslationHelperFunc) (mcp.Tool, mcp.ToolHandlerFor[map[string]any, any]) {
19+
tool := mcp.Tool{
20+
Name: "get_dependabot_alert",
21+
Description: t("TOOL_GET_DEPENDABOT_ALERT_DESCRIPTION", "Get details of a specific dependabot alert in a GitHub repository."),
22+
Annotations: &mcp.ToolAnnotations{
23+
Title: t("TOOL_GET_DEPENDABOT_ALERT_USER_TITLE", "Get dependabot alert"),
24+
ReadOnlyHint: true,
25+
},
26+
InputSchema: &jsonschema.Schema{
27+
Type: "object",
28+
Properties: map[string]*jsonschema.Schema{
29+
"owner": {
30+
Type: "string",
31+
Description: "The owner of the repository.",
32+
},
33+
"repo": {
34+
Type: "string",
35+
Description: "The name of the repository.",
36+
},
37+
"alertNumber": {
38+
Type: "number",
39+
Description: "The number of the alert.",
40+
},
41+
},
42+
Required: []string{"owner", "repo", "alertNumber"},
43+
},
44+
}
45+
46+
handler := mcp.ToolHandlerFor[map[string]any, any](func(ctx context.Context, _ *mcp.CallToolRequest, args map[string]any) (*mcp.CallToolResult, any, error) {
47+
owner, err := RequiredParam[string](args, "owner")
48+
if err != nil {
49+
return utils.NewToolResultError(err.Error()), nil, nil
50+
}
51+
repo, err := RequiredParam[string](args, "repo")
52+
if err != nil {
53+
return utils.NewToolResultError(err.Error()), nil, nil
54+
}
55+
alertNumber, err := RequiredInt(args, "alertNumber")
56+
if err != nil {
57+
return utils.NewToolResultError(err.Error()), nil, nil
58+
}
59+
60+
client, err := getClient(ctx)
61+
if err != nil {
62+
return utils.NewToolResultErrorFromErr("failed to get GitHub client", err), nil, nil
63+
}
64+
65+
alert, resp, err := client.Dependabot.GetRepoAlert(ctx, owner, repo, alertNumber)
66+
if err != nil {
67+
return ghErrors.NewGitHubAPIErrorResponse(ctx,
68+
fmt.Sprintf("failed to get alert with number '%d'", alertNumber),
69+
resp,
70+
err,
71+
), nil, nil
72+
}
73+
defer func() { _ = resp.Body.Close() }()
74+
75+
if resp.StatusCode != http.StatusOK {
76+
body, err := io.ReadAll(resp.Body)
77+
if err != nil {
78+
return utils.NewToolResultErrorFromErr("failed to read response body", err), nil, nil
79+
}
80+
return utils.NewToolResultError(fmt.Sprintf("failed to get alert: %s", string(body))), nil, nil
81+
}
82+
83+
r, err := json.Marshal(alert)
84+
if err != nil {
85+
return utils.NewToolResultErrorFromErr("failed to marshal alert", err), nil, nil
86+
}
87+
88+
return utils.NewToolResultText(string(r)), nil, nil
89+
})
90+
91+
return tool, handler
92+
}
93+
94+
func ListDependabotAlerts(getClient GetClientFn, t translations.TranslationHelperFunc) (mcp.Tool, mcp.ToolHandlerFor[map[string]any, any]) {
95+
tool := mcp.Tool{
96+
Name: "list_dependabot_alerts",
97+
Description: t("TOOL_LIST_DEPENDABOT_ALERTS_DESCRIPTION", "List dependabot alerts in a GitHub repository."),
98+
Annotations: &mcp.ToolAnnotations{
99+
Title: t("TOOL_LIST_DEPENDABOT_ALERTS_USER_TITLE", "List dependabot alerts"),
100+
ReadOnlyHint: true,
101+
},
102+
InputSchema: &jsonschema.Schema{
103+
Type: "object",
104+
Properties: map[string]*jsonschema.Schema{
105+
"owner": {
106+
Type: "string",
107+
Description: "The owner of the repository.",
108+
},
109+
"repo": {
110+
Type: "string",
111+
Description: "The name of the repository.",
112+
},
113+
"state": {
114+
Type: "string",
115+
Description: "Filter dependabot alerts by state. Defaults to open",
116+
Enum: []any{"open", "fixed", "dismissed", "auto_dismissed"},
117+
Default: json.RawMessage(`"open"`),
118+
},
119+
"severity": {
120+
Type: "string",
121+
Description: "Filter dependabot alerts by severity",
122+
Enum: []any{"low", "medium", "high", "critical"},
123+
},
124+
},
125+
Required: []string{"owner", "repo"},
126+
},
127+
}
128+
129+
handler := mcp.ToolHandlerFor[map[string]any, any](func(ctx context.Context, _ *mcp.CallToolRequest, args map[string]any) (*mcp.CallToolResult, any, error) {
130+
owner, err := RequiredParam[string](args, "owner")
131+
if err != nil {
132+
return utils.NewToolResultError(err.Error()), nil, nil
133+
}
134+
repo, err := RequiredParam[string](args, "repo")
135+
if err != nil {
136+
return utils.NewToolResultError(err.Error()), nil, nil
137+
}
138+
state, err := OptionalParam[string](args, "state")
139+
if err != nil {
140+
return utils.NewToolResultError(err.Error()), nil, nil
141+
}
142+
severity, err := OptionalParam[string](args, "severity")
143+
if err != nil {
144+
return utils.NewToolResultError(err.Error()), nil, nil
145+
}
146+
147+
client, err := getClient(ctx)
148+
if err != nil {
149+
return utils.NewToolResultErrorFromErr("failed to get GitHub client", err), nil, nil
150+
}
151+
152+
alerts, resp, err := client.Dependabot.ListRepoAlerts(ctx, owner, repo, &github.ListAlertsOptions{
153+
State: ToStringPtr(state),
154+
Severity: ToStringPtr(severity),
155+
})
156+
if err != nil {
157+
return ghErrors.NewGitHubAPIErrorResponse(ctx,
158+
fmt.Sprintf("failed to list alerts for repository '%s/%s'", owner, repo),
159+
resp,
160+
err,
161+
), nil, nil
162+
}
163+
defer func() { _ = resp.Body.Close() }()
164+
165+
if resp.StatusCode != http.StatusOK {
166+
body, err := io.ReadAll(resp.Body)
167+
if err != nil {
168+
return utils.NewToolResultErrorFromErr("failed to read response body", err), nil, nil
169+
}
170+
return utils.NewToolResultError(fmt.Sprintf("failed to list alerts: %s", string(body))), nil, nil
171+
}
172+
173+
r, err := json.Marshal(alerts)
174+
if err != nil {
175+
return utils.NewToolResultErrorFromErr("failed to marshal alerts", err), nil, nil
176+
}
177+
178+
return utils.NewToolResultText(string(r)), nil, nil
179+
})
180+
181+
return tool, handler
182+
}

0 commit comments

Comments
 (0)