Skip to content

Commit 6a05ac0

Browse files
committed
feat: add duffney/copacetic-mcp server implementation
Signed-off-by: Joshua Duffney <[email protected]>
1 parent ce32f36 commit 6a05ac0

File tree

23 files changed

+3092
-0
lines changed

23 files changed

+3092
-0
lines changed

.github/copilot-instructions.md

Lines changed: 293 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,293 @@
1+
# Copacetic MCP Server
2+
3+
## Project Overview
4+
5+
Copacetic MCP is a Go application that provides a Model Context Protocol (MCP) server for automated container image patching using Copacetic and Trivy. It exposes container patching capabilities through the MCP protocol, allowing AI agents and tools to patch container image vulnerabilities programmatically.
6+
7+
**Main commands**: MCP tools `version` and `patch`
8+
**Module**: `github.com/duffney/copacetic-mcp`
9+
10+
Always reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here.
11+
12+
## Folder Structure
13+
14+
- `main.go`: Main MCP server entry point
15+
- `cmd/client/main.go`: Test client for validating MCP server functionality
16+
- `internal/mcp/`: MCP server setup, tool registration, and protocol handlers
17+
- `internal/copa/`: Copacetic command execution and container patching logic
18+
- `internal/trivy/`: Trivy vulnerability scanning integration
19+
- `internal/types/`: Shared type definitions and execution modes
20+
- `internal/util/`: Utility functions for multiplatform support
21+
- `.goreleaser.yml`: GoReleaser configuration for cross-platform releases
22+
- `.github/workflows/`: CI/CD automation (build.yml, release.yml)
23+
- `Makefile`: Development tasks and build automation
24+
25+
## Libraries and Frameworks
26+
27+
- **MCP Protocol**: `github.com/modelcontextprotocol/go-sdk/mcp` for Model Context Protocol server implementation
28+
- **Container Registry**: `github.com/google/go-containerregistry` for container image operations
29+
- **Docker Integration**: `github.com/docker/docker` for container runtime operations
30+
- **VEX Support**: `github.com/openvex/go-vex` for vulnerability exchange document generation
31+
- **External Tools**: Copacetic (copa) for patching, Trivy for vulnerability scanning
32+
- **Cross-platform Builds**: GoReleaser for automated multi-platform binary releases
33+
34+
## Coding Standards
35+
36+
- Follow Go best practices and standard formatting (`make fmt`)
37+
- Use `go vet` for static analysis validation (`make vet`)
38+
- Implement comprehensive error handling with wrapped errors using `fmt.Errorf`
39+
- Write tests for new functionality with proper Docker test environment detection
40+
- Use structured logging for debugging and operational visibility
41+
- Follow MCP protocol specifications for tool definitions and responses
42+
- Handle multiplatform scenarios appropriately for container operations
43+
44+
## Key Architecture Concepts
45+
46+
- **MCP Server Architecture**: Provides multiple focused tools through stdin/stdout MCP protocol
47+
- **Tool Workflow**:
48+
- `scan-container`: Vulnerability scanning with Trivy (creates reports for targeted patching)
49+
- `patch-vulnerabilities`: Report-based patching (requires scan-container output)
50+
- `patch-platforms`: Platform-selective patching (no scan, patches specified platforms only)
51+
- `patch-comprehensive`: Comprehensive patching (no scan, patches all available platforms)
52+
- **Execution Modes**:
53+
- `report-based`: Patches only vulnerabilities identified through Trivy scanning
54+
- `platform-selective`: Patches specified platforms without vulnerability scanning
55+
- `comprehensive`: Patches all available platforms without vulnerability scanning
56+
- **Multiplatform Support**: Handles container images across multiple architectures (amd64, arm64, etc.)
57+
- **External Tool Integration**: Orchestrates Copacetic and Trivy through command execution
58+
- **VEX Generation**: Creates Vulnerability Exchange (VEX) documents for patching results
59+
- **Cross-platform Binary Distribution**: Builds native binaries for Linux, macOS, and Windows
60+
61+
## Supported Container Scenarios
62+
63+
- **Single-arch images**: Direct patching of images for specific platform
64+
- **Multi-arch images**: Platform-specific patching while preserving other architectures
65+
- **Registry Operations**: Pull, patch, and optionally push patched images
66+
- **Tag Management**: Automatic tagging of patched images with `-patched` suffix
67+
- **Vulnerability Reporting**: Integration with Trivy for security scanning
68+
69+
## Key Functions and Components
70+
71+
- `NewServer()`: Creates MCP server instance with registered tools
72+
- `Run()`: Starts MCP server with stdio transport
73+
- `Patch()`: Main patching tool that orchestrates vulnerability scanning and image patching
74+
- `Version()`: Returns Copacetic version information
75+
- `copa.Run()`: Executes Copacetic patching with proper argument construction
76+
- `trivy.Scan()`: Performs vulnerability scanning using Trivy
77+
- `DetermineExecutionMode()`: Selects appropriate patching strategy based on parameters
78+
79+
## Working Effectively
80+
81+
### Prerequisites and Installation
82+
83+
- Go 1.20 or later (tested with Go 1.24.6)
84+
- Docker (for container operations and some tests)
85+
- [Copacetic](https://github.com/project-copacetic/copacetic) v0.8.0+ for container patching
86+
- [Trivy](https://github.com/aquasecurity/trivy) v0.65.0+ for vulnerability scanning
87+
- [GoReleaser](https://goreleaser.com/) v2.5.0+ for releases
88+
89+
### Install Required Dependencies
90+
91+
Install Copacetic:
92+
93+
```bash
94+
wget -O copa.tar.gz https://github.com/project-copacetic/copacetic/releases/download/v0.8.0/copa_0.8.0_linux_amd64.tar.gz
95+
tar -xzf copa.tar.gz
96+
sudo cp copa /usr/local/bin/
97+
copa --version # Should show: copa version 0.8.0
98+
```
99+
100+
Install Trivy:
101+
102+
```bash
103+
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sudo sh -s -- -b /usr/local/bin
104+
trivy --version # Should show: Version: 0.65.0
105+
```
106+
107+
Install GoReleaser (for releases):
108+
109+
```bash
110+
curl -sLO https://github.com/goreleaser/goreleaser/releases/download/v2.5.0/goreleaser_Linux_x86_64.tar.gz
111+
tar -xzf goreleaser_Linux_x86_64.tar.gz
112+
sudo cp goreleaser /usr/local/bin/
113+
goreleaser --version # Should show version 2.5.0
114+
```
115+
116+
### Build and Test Commands
117+
118+
**NEVER CANCEL ANY BUILD OR TEST COMMAND** - All commands may take longer than expected. Always use adequate timeouts.
119+
120+
Build the project:
121+
122+
```bash
123+
make build # Takes ~40 seconds. NEVER CANCEL. Set timeout to 120+ seconds.
124+
```
125+
126+
Run tests:
127+
128+
```bash
129+
make test # Takes ~8 seconds. Docker tests are automatically skipped in CI.
130+
```
131+
132+
Format and validate code:
133+
134+
```bash
135+
make fmt # Takes ~0.2 seconds
136+
make vet # Takes ~5 seconds
137+
```
138+
139+
Cross-compile for all platforms:
140+
141+
```bash
142+
make cross-compile # Takes ~1 minute 45 seconds. NEVER CANCEL. Set timeout to 240+ seconds.
143+
```
144+
145+
Build release artifacts:
146+
147+
```bash
148+
make release-snapshot # Takes ~2 minutes 41 seconds. NEVER CANCEL. Set timeout to 300+ seconds.
149+
```
150+
151+
### Run the Application
152+
153+
Start the MCP server (interactive mode):
154+
155+
```bash
156+
./bin/copacetic-mcp-server
157+
# Server waits for MCP protocol messages on stdin/stdout
158+
# Use Ctrl+C to stop
159+
```
160+
161+
Run the test client (requires server dependencies):
162+
163+
```bash
164+
./bin/copacetic-mcp-client
165+
# Connects to server and tests the 'patch' tool with alpine:3.17
166+
```
167+
168+
## Validation
169+
170+
### Always Run These Steps After Making Changes:
171+
172+
1. **Build validation** - Build succeeds without errors:
173+
174+
```bash
175+
make build # Set timeout to 120+ seconds, NEVER CANCEL
176+
```
177+
178+
2. **Test validation** - All tests pass:
179+
180+
```bash
181+
make test # Docker tests skip automatically in CI environments
182+
```
183+
184+
3. **Code quality validation** - Required for CI to pass:
185+
186+
```bash
187+
make fmt vet # Both commands must complete successfully
188+
```
189+
190+
4. **MCP server functionality validation** - Test server-client communication:
191+
```bash
192+
# Create test script to validate version tool:
193+
cat > test_mcp.go << 'EOF'
194+
package main
195+
import (
196+
"context"
197+
"fmt"
198+
"log"
199+
"os/exec"
200+
"github.com/modelcontextprotocol/go-sdk/mcp"
201+
)
202+
func main() {
203+
ctx := context.Background()
204+
client := mcp.NewClient(&mcp.Implementation{Name: "test-client", Version: "v1.0.0"}, nil)
205+
cmd := exec.Command("./bin/copacetic-mcp-server")
206+
transport := mcp.NewCommandTransport(cmd)
207+
session, err := client.Connect(ctx, transport)
208+
if err != nil { log.Fatal(err) }
209+
defer session.Close()
210+
params := &mcp.CallToolParams{Name: "version", Arguments: map[string]any{}}
211+
res, err := session.CallTool(ctx, params)
212+
if err != nil { log.Fatalf("CallTool failed: %v", err) }
213+
if res.IsError { log.Fatal("version tool failed") }
214+
for _, c := range res.Content {
215+
fmt.Printf("Success: %s\n", c.(*mcp.TextContent).Text)
216+
}
217+
}
218+
EOF
219+
go run test_mcp.go # Should output: Success: copa version 0.8.0
220+
rm test_mcp.go
221+
```
222+
223+
### Cross-Platform Validation
224+
225+
For release builds, validate cross-compilation works:
226+
227+
```bash
228+
make cross-compile # Set timeout to 240+ seconds, NEVER CANCEL
229+
ls -la bin/ # Should show binaries for linux-amd64, linux-arm64, darwin-amd64, darwin-arm64, windows-amd64.exe
230+
```
231+
232+
## Important Build and Timing Information
233+
234+
- **Build time**: ~40 seconds (first time with dependencies)
235+
- **Test time**: ~8 seconds (Docker tests automatically skip in CI)
236+
- **Cross-compile time**: ~1 minute 45 seconds
237+
- **Release build time**: ~2 minutes 41 seconds
238+
- **Format/vet time**: <5 seconds combined
239+
240+
**CRITICAL**: NEVER CANCEL long-running commands. Builds and cross-compilation can take several minutes, especially on slower systems. Always set timeouts to at least double the expected time.
241+
242+
## Common Tasks and Troubleshooting
243+
244+
### MCP Server Architecture
245+
246+
The server provides two MCP tools:
247+
248+
- `version`: Returns copa version information
249+
- `patch`: Patches container images using Copacetic
250+
251+
### Dependencies Not Available
252+
253+
If copa or trivy are not installed:
254+
255+
- Tests will still pass (external tool tests are conditional)
256+
- MCP server will fail when tools are called
257+
- Always install dependencies using the exact commands above
258+
259+
### Docker Tests Skipped
260+
261+
Docker tests automatically skip in CI environments (`CI` or `GITHUB_ACTIONS` env vars set). This is expected behavior.
262+
263+
### Build Artifacts
264+
265+
- Binaries: `bin/copacetic-mcp-server`, `bin/copacetic-mcp-client`
266+
- Cross-compiled: `bin/copacetic-mcp-server-{os}-{arch}[.exe]`
267+
- Release artifacts: `dist/` directory (excluded from git)
268+
269+
### Key Project Structure
270+
271+
```
272+
copacetic-mcp/
273+
├── main.go # Main MCP server entry point
274+
├── cmd/client/main.go # Test client for MCP server validation
275+
├── internal/
276+
│ ├── mcp/ # MCP server handlers, tool registration, protocol implementation
277+
│ ├── copa/ # Copacetic command execution and container patching orchestration
278+
│ ├── trivy/ # Trivy vulnerability scanning integration
279+
│ ├── types/ # Shared type definitions, execution modes, and parameters
280+
│ └── util/ # Utility functions for multiplatform and cross-platform support
281+
├── .goreleaser.yml # GoReleaser configuration for automated releases
282+
├── .github/workflows/ # GitHub Actions CI/CD automation
283+
│ ├── build.yml # Continuous integration: build, test, lint on every push/PR
284+
│ └── release.yml # Automated releases with cross-platform binaries on tags
285+
└── Makefile # Development tasks: build, test, format, cross-compile, release
286+
```
287+
288+
## CI/CD Integration
289+
290+
- GitHub Actions automatically builds and tests on push/PR
291+
- Release process uses GoReleaser for cross-platform binaries
292+
- Docker tests are automatically skipped in CI environments
293+
- All validation steps (fmt, vet, test, build) must pass for CI success

.github/workflows/build.yml

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
name: Build and Test
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- uses: actions/checkout@v4
15+
16+
- name: Set up Go
17+
uses: actions/setup-go@v5
18+
with:
19+
go-version: stable
20+
cache: true
21+
22+
- name: Verify dependencies
23+
run: go mod verify
24+
25+
- name: Build server
26+
run: go build -v ./
27+
28+
- name: Build client
29+
run: go build -v ./cmd/client
30+
31+
- name: Run tests
32+
run: go test -v ./...
33+
# Note: Docker-dependent tests are automatically skipped in CI environments
34+
35+
- name: Check formatting
36+
run: |
37+
if [ "$(gofmt -s -l . | wc -l)" -gt 0 ]; then
38+
echo "Code is not formatted properly:"
39+
gofmt -s -l .
40+
exit 1
41+
fi
42+
43+
- name: Run vet
44+
run: go vet ./...
45+
46+
build-cross-platform:
47+
runs-on: ubuntu-latest
48+
needs: test
49+
strategy:
50+
matrix:
51+
goos: [linux, darwin, windows]
52+
goarch: [amd64, arm64]
53+
exclude:
54+
# Windows ARM64 builds may not be needed
55+
- goos: windows
56+
goarch: arm64
57+
58+
steps:
59+
- uses: actions/checkout@v4
60+
61+
- name: Set up Go
62+
uses: actions/setup-go@v5
63+
with:
64+
go-version: "1.21"
65+
cache: true
66+
67+
- name: Build ${{ matrix.goos }}/${{ matrix.goarch }}
68+
env:
69+
GOOS: ${{ matrix.goos }}
70+
GOARCH: ${{ matrix.goarch }}
71+
CGO_ENABLED: 0
72+
run: |
73+
go build -o copacetic-mcp-server-${{ matrix.goos }}-${{ matrix.goarch }}${{ matrix.goos == 'windows' && '.exe' || '' }} .
74+
go build -o copacetic-mcp-client-${{ matrix.goos }}-${{ matrix.goarch }}${{ matrix.goos == 'windows' && '.exe' || '' }} ./cmd/client
75+
76+
- name: Upload artifacts
77+
uses: actions/upload-artifact@v4
78+
with:
79+
name: binaries-${{ matrix.goos }}-${{ matrix.goarch }}
80+
path: |
81+
copacetic-mcp-server-*
82+
copacetic-mcp-client-*
83+
retention-days: 30

0 commit comments

Comments
 (0)