|
| 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 |
0 commit comments