Skip to content

Add tool to report security vulnerability#2406

Draft
grconm wants to merge 1 commit intomainfrom
grconm_add_report_advisories_tool
Draft

Add tool to report security vulnerability#2406
grconm wants to merge 1 commit intomainfrom
grconm_add_report_advisories_tool

Conversation

@grconm
Copy link
Copy Markdown

@grconm grconm commented Apr 29, 2026

Summary

A

Why

Fixes #

What changed

MCP impact

  • No tool or API changes
  • Tool schema or behavior changed
  • New tool added

Prompts tested (tool changes only)

Security / limits

  • No security or limits impact
  • Auth / permissions considered
  • Data exposure, filtering, or token/size limits considered

Tool renaming

  • I am renaming tools as part of this PR (e.g. a part of a consolidation effort)
    • I have added the new tool aliases in deprecated_tool_aliases.go
  • I am not renaming tools as part of this PR

Note: if you're renaming tools, you must add the tool aliases. For more information on how to do so, please refer to the official docs.

Lint & tests

  • Linted locally with ./script/lint
  • Tested locally with ./script/test

Docs

  • Not needed
  • Updated (README / docs / examples)

Copilot AI review requested due to automatic review settings April 29, 2026 21:21
@grconm grconm requested a review from a team as a code owner April 29, 2026 21:21
@grconm grconm marked this pull request as draft April 29, 2026 21:21
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new MCP tool to let users report a security vulnerability for a repository by creating a private security advisory in “triage” state, integrating it into the existing Security Advisories toolset and documentation.

Changes:

  • Registers a new report_security_vulnerability tool in the global tool inventory.
  • Implements the tool handler and input schema in security_advisories.go.
  • Adds unit tests, toolsnap snapshot, and README tool documentation for the new tool.
Show a summary per file
File Description
pkg/github/tools.go Registers the new tool in AllTools.
pkg/github/security_advisories.go Implements ReportSecurityVulnerability tool schema + handler logic.
pkg/github/security_advisories_test.go Adds tests for tool schema snapshot + handler behavior.
pkg/github/toolsnaps/report_security_vulnerability.snap Adds schema snapshot for the new tool.
README.md Documents the new tool and its parameters/scopes.

Copilot's findings

Comments suppressed due to low confidence (1)

pkg/github/security_advisories.go:707

  • API failures from client.Do are returned as a Go error (fmt.Errorf("failed to report security vulnerability: %w", err)), while most tools return an MCP error result via ghErrors.NewGitHubAPIErrorResponse(...) to preserve error details in-context and keep handler errors (err return) reserved for unexpected/internal failures. Also note that with github.Client.Do, non-2xx responses typically come back as err != nil, so the resp.StatusCode != http.StatusCreated branch is effectively dead for 4xx/5xx and may not capture the response body as intended.
			var advisory github.SecurityAdvisory
			resp, err := client.Do(ctx, req, &advisory)
			if err != nil {
				return nil, nil, fmt.Errorf("failed to report security vulnerability: %w", err)
			}
			defer func() { _ = resp.Body.Close() }()

			if resp.StatusCode != http.StatusCreated {
				body, err := io.ReadAll(resp.Body)
				if err != nil {
					return nil, nil, fmt.Errorf("failed to read response body: %w", err)
				}
				return ghErrors.NewGitHubAPIStatusErrorResponse(ctx, "failed to report security vulnerability", resp, body), nil, nil
			}
  • Files reviewed: 5/5 changed files
  • Comments generated: 3

Comment on lines +722 to +730
// For validation errors, err is nil but result.IsError is true
// For API errors, err is not nil
if err != nil {
assert.Contains(t, err.Error(), tc.expectedErrMsg)
} else {
require.True(t, result.IsError)
text := getTextResult(t, result).Text
assert.Contains(t, text, tc.expectedErrMsg)
}

client, err := deps.GetClient(ctx)
if err != nil {
return nil, nil, fmt.Errorf("failed to get GitHub client: %w", err)
Comment on lines +636 to +680
// Handle vulnerabilities array
if vulnsData, ok := args["vulnerabilities"]; ok {
if vulnsArray, ok := vulnsData.([]any); ok {
var vulnerabilities []*github.AdvisoryVulnerability
for _, v := range vulnsArray {
if vulnMap, ok := v.(map[string]any); ok {
vuln := &github.AdvisoryVulnerability{}

// Parse package
if pkgData, ok := vulnMap["package"].(map[string]any); ok {
pkg := &github.VulnerabilityPackage{}
if ecosystem, ok := pkgData["ecosystem"].(string); ok {
pkg.Ecosystem = &ecosystem
}
if name, ok := pkgData["name"].(string); ok {
pkg.Name = &name
}
vuln.Package = pkg
}

// Parse other fields
if versionRange, ok := vulnMap["vulnerable_version_range"].(string); ok {
vuln.VulnerableVersionRange = &versionRange
}
if patchedVersions, ok := vulnMap["patched_versions"].(string); ok {
vuln.PatchedVersions = &patchedVersions
}
if vulnFuncs, ok := vulnMap["vulnerable_functions"].([]any); ok {
var functions []string
for _, f := range vulnFuncs {
if funcStr, ok := f.(string); ok {
functions = append(functions, funcStr)
}
}
if len(functions) > 0 {
vuln.VulnerableFunctions = functions
}
}

vulnerabilities = append(vulnerabilities, vuln)
}
}
report.Vulnerabilities = &vulnerabilities
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants