Skip to content

Add tool to report security vulnerability#2406

Draft
grconm wants to merge 1 commit into
mainfrom
grconm_add_report_advisories_tool
Draft

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

Conversation

@grconm

@grconm grconm commented Apr 29, 2026

Copy link
Copy Markdown

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

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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

3 participants