Conversation
- Introduce clientError type to distinguish non-retryable 4xx from retryable 5xx HTTP errors in upload and analysis packages - Populate ScanMetadata.Version in upload payload - Add test suite for internal/pipeline with 10 tests (96.5% coverage) - Add test suite for internal/output with 8 tests (88.3% coverage) - Add test suite for internal/analysis with 7 tests (88.7% coverage) - Add test suite for internal/upload with 7 tests (86.8% coverage) - Add test suite for internal/tlsutil with 5 tests (87.5% coverage) - Add test suite for internal/cli with 4 tests (46.9% coverage) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… tests - Implement MCP server mode using go-sdk with scan and get_scan_results tools, background periodic scanning, and install command - Add per-status-code error messages in analysis API (401, 413, 429) - Add command resolution fallback paths for nvm, pyenv, cargo, homebrew - Add traffic capture wrapper for MCP transport debugging - Build E2E test infrastructure with math and weather test MCP servers - Add 5 E2E tests verifying full scan pipeline end-to-end Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds MCP server support and supporting infrastructure so agent-scanner can run as an MCP server (with install helpers), improve command resolution, capture MCP traffic for debugging, and validate behavior via unit + E2E tests.
Changes:
- Implement MCP server mode (
mcp-server) withscan/get_scan_resultstools and optional background scanning, plus an install command for Claude Desktop config. - Add command resolution fallback paths and an MCP transport wrapper for JSON-RPC traffic capture.
- Expand automated testing: uploader/analyzer retry semantics, output formatting, TLS utils, pipeline behavior, MCP server behavior, and E2E coverage with purpose-built test servers.
Reviewed changes
Copilot reviewed 26 out of 27 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| internal/upload/uploader.go | Adds scan metadata + retry behavior tweaks for control-server uploads. |
| internal/upload/uploader_test.go | Tests upload behavior: success, retries, headers, metadata, cancellation. |
| internal/tlsutil/tlsutil_test.go | Adds tests for transport cloning and TLS config cloning behavior. |
| internal/testserver/protocol.go | Minimal JSON-RPC protocol helpers for test servers. |
| internal/testserver/math_server.go | Clean MCP test server (math tools) for E2E coverage. |
| internal/testserver/weather_server.go | “Malicious” MCP test server (suspicious tool descriptions) for E2E coverage. |
| internal/pipeline/pipeline_test.go | Adds unit tests validating pipeline stage execution and error tolerance. |
| internal/output/output_test.go | Adds tests for text + JSON formatting and truncation behavior. |
| internal/mcpserver/server.go | Implements MCP server + tool handlers + background scan loop + cached results. |
| internal/mcpserver/server_test.go | Validates MCP tool registration, scan caching, summary building, concurrency. |
| internal/mcpserver/install.go | Implements Claude Desktop config installation helper. |
| internal/mcpserver/install_test.go | Tests default config path + install behavior across scenarios. |
| internal/mcpclient/stdio.go | Switches stdio command lookup to resolveCommand fallback resolver. |
| internal/mcpclient/resolve.go | Implements PATH + fallback-dir command resolution. |
| internal/mcpclient/resolve_test.go | Tests command resolution fallback + executable detection. |
| internal/mcpclient/capture.go | Implements transport wrapper capturing sent/received JSON-RPC messages. |
| internal/mcpclient/capture_test.go | Tests capture wrapper behavior and message recording semantics. |
| internal/e2e/e2e_test.go | End-to-end pipeline tests against built test MCP servers + formatter checks. |
| internal/cli/mcpserver.go | Wires CLI mcp-server command to pipeline + MCP server runner. |
| internal/cli/install.go | Wires CLI install-mcp-server command to installer. |
| internal/cli/cli_test.go | Adds tests for parsing control-server CLI args. |
| internal/analysis/analyzer.go | Adds per-status-code error messaging + retry/no-retry semantics. |
| internal/analysis/analyzer_test.go | Tests analyzer behavior: retries, error handling, nil signature skipping. |
| cmd/testserver-math/main.go | Entry point for math MCP test server binary. |
| cmd/testserver-weather/main.go | Entry point for weather MCP test server binary. |
| go.mod | Adds MCP go-sdk dependency (and related indirect deps). |
| go.sum | Locks new dependency checksums. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Return errors instead of nil on JSON marshal failures in MCP server handlers - Copy slices in ScanState.Set/Get to prevent callers from mutating cached data - Deep-clone server configs before redaction to avoid mutating caller results - Fix install command to assign default config path before calling InstallServer - Remove unused ClientName field and --client-name CLI flag - Simplify uploader test to use errors.As directly, remove containsClientError - Add runtime.GOOS skip guards for Windows on Unix-specific resolve tests Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 27 out of 28 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Search system fallback dirs even when home directory is unavailable - Deep-copy JSONRPCMessage in capture transport to prevent mutation - Return error when mcpServers config key has unexpected type Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 27 out of 28 changed files in this pull request and generated 6 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Use cancelable context in RunServer so background goroutines exit cleanly - Deep-copy messages in CaptureTransport.Messages() to prevent caller mutation - Clone ScanError pointers before redaction to avoid mutating caller data - Compare transport defaults against http.DefaultTransport instead of hardcoded values - Add Windows .exe suffix for E2E test server binaries Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 27 out of 28 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 27 out of 28 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
The test previously only exercised sequential Set/Get. Add goroutine-based concurrent access to actually validate thread safety under the race detector. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 27 out of 28 changed files in this pull request and generated 6 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…shutdown Thread cmd.Context() from the CLI through to RunServer so that SIGINT/cancellation propagates to background scan goroutines. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 27 out of 28 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Gate E2E tests behind testing.Short() to avoid slow go build in CI - Treat empty/whitespace-only config files as empty objects in install Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 27 out of 28 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…eaks Ensure the wrapped receive channel is created exactly once, so repeated Receive() calls return the same channel instead of spawning extra goroutines that split messages unpredictably. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
testing.Short() panics when called before flag.Parse() in TestMain. Use an environment variable gate instead. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 27 out of 28 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Strip JSONC comments before unmarshaling in install command - Remove duplicate status code in analyzer error messages - Use atomic.Bool for scanCalled in server test to avoid race Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 27 out of 28 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
E2E tests build external binaries and are slow. Using a build tag excludes them from default 'go test ./...' runs. Run explicitly with 'go test -tags e2e ./internal/e2e/...'. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 27 out of 28 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Integrate changes from main (PRs #4, #5) into phase3-4 branch: - Keep nonRetryableError type and retry guard in analyzer and uploader - Use atomic.Bool for thread-safe test variables - Use sanitizeBodySnippet with io.LimitReader for safe error body handling - Use more reliable test timeouts (4s/5s instead of 1500ms) - Remove unused statusMessage function (replaced by sanitizeBodySnippet) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 20 out of 21 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Redact env vars and headers from scan results before caching and returning to MCP clients to prevent credential leakage - Clamp negative ScanInterval to default 30m to prevent time.NewTicker panic from user-provided CLI flags - Add tests for redaction behavior and negative interval handling Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Extract shared runServer helper to eliminate duplicated stdin scanner loop - Define DirectionSent and DirectionReceived constants for capture messages - Use redacted results for buildSummary instead of original unredacted data Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Document mcp-server command with --tool and --scan-interval options - Document install-mcp-server command for Claude Desktop integration - Add MCP server mode to features list Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
mcp-serverandinstall-mcp-servercommands usinggo-sdk, exposingscanandget_scan_resultstools with background periodic scanningresolveCommand()searches nvm, npm-global, yarn, pyenv, cargo, homebrew, and~/.local/binwhenexec.LookPathfailsCaptureTransportwraps any MCP transport to record all sent/received JSON-RPC messages for debuggingNew packages/files
internal/mcpserver/server.gointernal/mcpserver/install.gointernal/mcpclient/resolve.gointernal/mcpclient/capture.gointernal/testserver/internal/e2e/Test plan
make test— all 80+ tests pass with race detectormake lint— 0 lint issuesmake build— compiles successfully🤖 Generated with Claude Code