Skip to content

Commit 23f6f3a

Browse files
authored
Add Dependabot Alert Tools (#631)
* add dependabit get and list tools * add toolsnaps * add unit tests for new tools * generate-docs
1 parent f88456f commit 23f6f3a

File tree

7 files changed

+547
-0
lines changed

7 files changed

+547
-0
lines changed

README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ The following sets of tools are available (all are on by default):
269269
| `context` | **Strongly recommended**: Tools that provide context about the current user and GitHub context you are operating in |
270270
| `actions` | GitHub Actions workflows and CI/CD operations |
271271
| `code_security` | Code security related tools, such as GitHub Code Scanning |
272+
| `dependabot` | Dependabot tools |
272273
| `discussions` | GitHub Discussions related tools |
273274
| `experiments` | Experimental features that are not considered stable yet |
274275
| `issues` | GitHub Issues related tools |
@@ -555,6 +556,23 @@ export GITHUB_MCP_TOOL_ADD_ISSUE_COMMENT_DESCRIPTION="an alternative description
555556

556557
<details>
557558

559+
<summary>Dependabot</summary>
560+
561+
- **get_dependabot_alert** - Get dependabot alert
562+
- `alertNumber`: The number of the alert. (number, required)
563+
- `owner`: The owner of the repository. (string, required)
564+
- `repo`: The name of the repository. (string, required)
565+
566+
- **list_dependabot_alerts** - List dependabot alerts
567+
- `owner`: The owner of the repository. (string, required)
568+
- `repo`: The name of the repository. (string, required)
569+
- `severity`: Filter dependabot alerts by severity (string, optional)
570+
- `state`: Filter dependabot alerts by state. Defaults to open (string, optional)
571+
572+
</details>
573+
574+
<details>
575+
558576
<summary>Discussions</summary>
559577

560578
- **get_discussion** - Get discussion

docs/remote-server.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Below is a table of available toolsets for the remote GitHub MCP Server. Each to
2020
| all | All available GitHub MCP tools | https://api.githubcopilot.com/mcp/ | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=github&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2F%22%7D) | [read-only](https://api.githubcopilot.com/mcp/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=github&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Freadonly%22%7D) |
2121
| Actions | GitHub Actions workflows and CI/CD operations | https://api.githubcopilot.com/mcp/x/actions | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-actions&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Factions%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/actions/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-actions&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Factions%2Freadonly%22%7D) |
2222
| Code Security | Code security related tools, such as GitHub Code Scanning | https://api.githubcopilot.com/mcp/x/code_security | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-code_security&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fcode_security%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/code_security/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-code_security&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fcode_security%2Freadonly%22%7D) |
23+
| Dependabot | Dependabot tools | https://api.githubcopilot.com/mcp/x/dependabot | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-dependabot&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fdependabot%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/dependabot/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-dependabot&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fdependabot%2Freadonly%22%7D) |
2324
| Discussions | GitHub Discussions related tools | https://api.githubcopilot.com/mcp/x/discussions | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-discussions&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fdiscussions%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/discussions/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-discussions&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fdiscussions%2Freadonly%22%7D) |
2425
| Experiments | Experimental features that are not considered stable yet | https://api.githubcopilot.com/mcp/x/experiments | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-experiments&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fexperiments%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/experiments/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-experiments&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fexperiments%2Freadonly%22%7D) |
2526
| Issues | GitHub Issues related tools | https://api.githubcopilot.com/mcp/x/issues | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-issues&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fissues%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/issues/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-issues&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fissues%2Freadonly%22%7D) |
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"annotations": {
3+
"title": "Get dependabot alert",
4+
"readOnlyHint": true
5+
},
6+
"description": "Get details of a specific dependabot alert in a GitHub repository.",
7+
"inputSchema": {
8+
"properties": {
9+
"alertNumber": {
10+
"description": "The number of the alert.",
11+
"type": "number"
12+
},
13+
"owner": {
14+
"description": "The owner of the repository.",
15+
"type": "string"
16+
},
17+
"repo": {
18+
"description": "The name of the repository.",
19+
"type": "string"
20+
}
21+
},
22+
"required": [
23+
"owner",
24+
"repo",
25+
"alertNumber"
26+
],
27+
"type": "object"
28+
},
29+
"name": "get_dependabot_alert"
30+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
{
2+
"annotations": {
3+
"title": "List dependabot alerts",
4+
"readOnlyHint": true
5+
},
6+
"description": "List dependabot alerts in a GitHub repository.",
7+
"inputSchema": {
8+
"properties": {
9+
"owner": {
10+
"description": "The owner of the repository.",
11+
"type": "string"
12+
},
13+
"repo": {
14+
"description": "The name of the repository.",
15+
"type": "string"
16+
},
17+
"severity": {
18+
"description": "Filter dependabot alerts by severity",
19+
"enum": [
20+
"low",
21+
"medium",
22+
"high",
23+
"critical"
24+
],
25+
"type": "string"
26+
},
27+
"state": {
28+
"default": "open",
29+
"description": "Filter dependabot alerts by state. Defaults to open",
30+
"enum": [
31+
"open",
32+
"fixed",
33+
"dismissed",
34+
"auto_dismissed"
35+
],
36+
"type": "string"
37+
}
38+
},
39+
"required": [
40+
"owner",
41+
"repo"
42+
],
43+
"type": "object"
44+
},
45+
"name": "list_dependabot_alerts"
46+
}

pkg/github/dependabot.go

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
package github
2+
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/v72/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+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy