Skip to content

Commit aacaba4

Browse files
authored
feat: switch to resource results (#27)
1 parent 5b91ad5 commit aacaba4

File tree

7 files changed

+56
-149
lines changed

7 files changed

+56
-149
lines changed

.github/workflows/lint.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@ jobs:
1919
with:
2020
go-version-file: go.mod
2121

22+
- name: Check formatting
23+
run: |
24+
make format
25+
if ! git diff --exit-code; then
26+
echo "Files are not formatted correctly. Run 'make format' locally and commit changes."
27+
exit 1
28+
fi
29+
2230
- uses: golangci/golangci-lint-action@v6
2331
with:
2432
version: v1.64.2

.github/workflows/test.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: Test
2+
3+
on:
4+
pull_request:
5+
paths:
6+
- '**/*.go'
7+
8+
permissions:
9+
contents: read
10+
pull-requests: read
11+
12+
jobs:
13+
golangci:
14+
name: test
15+
runs-on: ubuntu-latest
16+
steps:
17+
- uses: actions/checkout@v4
18+
- uses: actions/setup-go@v5
19+
with:
20+
go-version-file: go.mod
21+
22+
- run: make test

Makefile

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,18 +57,18 @@ install-plugin: add-plugin-manifest
5757
go build -ldflags "-s -w -X github.com/aquasecurity/trivy-mcp/pkg/version.TrivyVersion=$${trivy_version}" -o ~/.trivy/plugins/mcp/trivy-mcp ./cmd/trivy-mcp/main.go;
5858
@echo "Plugin installed successfully."
5959

60-
# Install plugin with Aqua support
61-
.PHONY: install-plugin-aqua
62-
install-plugin-aqua:
63-
$(MAKE) install-plugin BUILDTAGS=aqua
64-
6560
.PHONY: run
6661
run:
6762
@trivy_version=$$(cat go.mod | grep 'github.com/aquasecurity/trivy v' | awk '{ print $$2}') ;\
6863
echo Current trivy version: $$trivy_version ;\
6964
go build -ldflags "-s -w -X github.com/aquasecurity/trivy-mcp/pkg/version.TrivyVersion=$${trivy_version}" -o trivy-mcp ./cmd/trivy-mcp/main.go;
7065
@./trivy-mcp help
7166

67+
.PHONY: format
68+
format:
69+
@echo "Running gofmt..."
70+
@gofmt -w -s -d .
71+
7272
.PHONY: lint
7373
lint:
7474
@which golangci-lint || go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.64.2

pkg/tools/scan/scan.go

Lines changed: 15 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package scan
22

33
import (
44
"context"
5-
"encoding/json"
65
"errors"
76
"fmt"
87
"os"
@@ -15,7 +14,6 @@ import (
1514
"github.com/aquasecurity/trivy-mcp/pkg/flag"
1615
"github.com/aquasecurity/trivy/pkg/commands"
1716
"github.com/aquasecurity/trivy/pkg/log"
18-
"github.com/aquasecurity/trivy/pkg/types"
1917
"github.com/mark3labs/mcp-go/mcp"
2018

2119
_ "modernc.org/sqlite" // sqlite driver for RPM DB and Java DB
@@ -33,7 +31,7 @@ func NewScanTools(opts flag.Options, trivyTempDir string) *ScanTools {
3331
trivyBinary: opts.TrivyBinary,
3432
debug: opts.Debug,
3533
useAquaPlatform: opts.UseAquaPlatform,
36-
trivyTempDir: filepath.Join(os.TempDir(), "trivy"),
34+
trivyTempDir: trivyTempDir,
3735
}
3836
}
3937

@@ -162,54 +160,30 @@ func (t *ScanTools) ScanWithTrivyHandler(ctx context.Context, request mcp.CallTo
162160
return result, nil
163161
}
164162

165-
f, err := os.Open(resultsFilePath)
166-
if err != nil {
167-
logger.Error("Failed to open scan results file", log.Err(err))
168-
return nil, errors.New("failed to open scan results file")
169-
}
170-
171163
defer func() {
172-
if err := f.Close(); err != nil {
173-
logger.Error("Failed to close scan results file", log.Err(err))
174-
}
175164
if err := os.Remove(resultsFilePath); err != nil {
176-
logger.Error("Failed to remove scan results file", log.Err(err))
165+
logger.Error("Failed to remove results file", log.Err(err))
177166
}
178-
logger.Debug("Scan results file removed", log.String("file", resultsFilePath))
179167
}()
180168

181-
var r types.Report
182-
if err = json.NewDecoder(f).Decode(&r); err != nil {
183-
logger.Error("Failed to decode scan results", log.Err(err))
184-
return nil, fmt.Errorf("failed to decode scan results: %w", err)
185-
}
186-
187-
var totalCount int
188-
for _, result := range r.Results {
189-
totalCount += len(result.Vulnerabilities) + len(result.Misconfigurations) + len(result.Licenses) + len(result.Secrets)
190-
}
191-
192-
if totalCount == 0 {
193-
return mcp.NewToolResultText("No vulnerabilities found\n"), nil
194-
}
195-
196-
var output string
197-
198-
// 100 is an arbitrary number, but it seems to be a good threshold for the amount of data to display
199-
// we can tune this, but we need to be careful about the context window size and not overloading the results
200-
if totalCount > 100 {
201-
output, err = executeTemplate(summaryTemplate, r.Results)
202-
} else {
203-
output, err = executeTemplate(resultTemplate, r.Results)
204-
}
169+
content, err := os.ReadFile(resultsFilePath)
205170
if err != nil {
206-
logger.Error("Failed to format results", log.Err(err))
207-
return nil, fmt.Errorf("failed to format results: %w", err)
171+
logger.Error("Failed to read scan results file", log.Err(err))
172+
return nil, errors.New("failed to read scan results file")
208173
}
209174

210-
return mcp.NewToolResultText(output), nil
175+
return mcp.NewToolResultResource(
176+
"The embedded resource is a human readable JSON format and found at the filepath that can be further processed.",
177+
mcp.TextResourceContents{
178+
URI: resultsFilePath,
179+
Text: string(content),
180+
},
181+
), nil
211182
}
212183

184+
// processSBOMResult processes the SBOM result and returns a tool result
185+
// we don't clean up the results file here because we want to keep it to be available for the LLM to provide a link
186+
// when the MCP server is closed, the trivy mcp cache should be cleaned up
213187
func (*ScanTools) processSBOMResult(resultsFilePath string, logger *log.Logger, filename string) (*mcp.CallToolResult, error) {
214188
log.Debug("Scan results file", log.String("file", resultsFilePath))
215189

pkg/tools/scan/scan_args.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ var (
2323
availableSeverities = []string{"CRITICAL", "HIGH", "MEDIUM", "LOW", "UNKNOWN"}
2424
defaultSeverity = "CRITICAL"
2525

26-
availableOutputFormats = []string{"json", "table", "template", "cyclonedx", "spdx", "spdx-json"}
26+
availableOutputFormats = []string{"json", "cyclonedx", "spdx", "spdx-json"}
2727
defaultOutputFormat = "json"
2828
)
2929

@@ -59,7 +59,9 @@ var severityArray = mcp.WithArray("severities",
5959

6060
var outputFormatString = mcp.WithString("outputFormat",
6161
mcp.Required(),
62-
mcp.Description("The format of the output. When generating an SBOM report you can use either cyclonedx or spdx. For sbom, prefer cyclonedx. If the user requests spdx, use spdx rather than spdx-json."),
62+
mcp.Description(`The format of the output which should normally be json. \n
63+
When generating an SBOM report you can use either cyclonedx or spdx. For sbom, prefer cyclonedx. \n
64+
If the user requests spdx, use spdx rather than spdx-json.`),
6365
mcp.Enum(availableOutputFormats...),
6466
mcp.DefaultString(defaultOutputFormat),
6567
)

pkg/tools/scan/templates.go

Lines changed: 0 additions & 100 deletions
This file was deleted.

pkg/tools/version/version_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"testing"
66

77
"github.com/aquasecurity/trivy-mcp/pkg/flag"
8+
"github.com/aquasecurity/trivy-mcp/pkg/version"
89
"github.com/mark3labs/mcp-go/mcp"
910
"github.com/stretchr/testify/assert"
1011
"github.com/stretchr/testify/require"
@@ -19,7 +20,7 @@ func TestVersionHandler(t *testing.T) {
1920
{
2021
name: "Trivy Binary Not Specified",
2122
trivyBinary: "",
22-
expected: "v0.62.0",
23+
expected: version.TrivyVersion,
2324
},
2425
}
2526

0 commit comments

Comments
 (0)