Update on vibecop, my open-source linter for AI-generated code. v0.4.0 is the biggest release yet: 48 files changed, 10,720 lines added, 30 new tests (540 total).
Three major changes and the engineering story behind each.
MCP (Model Context Protocol) launched in late 2024. Every MCP server on GitHub was essentially built in the AI era. We pointed vibecop at 5 of the most popular ones to see what AI-generated infrastructure code actually looks like.
DesktopCommanderMCP (5.8K stars): 18 instances of execSync() or exec() with dynamic string arguments. This is a tool that runs shell commands on your machine. 18 potential command injection points. Also 137 god-functions and 107 excessive-any type annotations.
mcp-atlassian (4.8K stars): 84 test functions with zero assertions. They pass, they prove nothing. Another 77 tests hide assertions behind if statements, so depending on runtime conditions, the assertions may never execute.
notion-mcp-server (4.2K stars): A startServer function that's 260 lines long with cyclomatic complexity 49. That means 49 independent paths through one function.
exa-mcp-server (4.2K stars): Tool registration functions consistently hitting 100-200 lines with complexity 14-34. Classic AI generation: copy the function, change the specifics, never refactor.
Figma-Context-MCP (14.2K stars): 16 god-functions and 3 test files with zero error path testing.
These are repos with 4K-14K stars, used by thousands of developers. The code works. The code is also structurally fragile.
This was the real engineering story of this release.
Our first scan of DesktopCommanderMCP returned 500+ findings. We got excited. Then we looked at the breakdown: 457 were "console.log left in production code." But DesktopCommanderMCP IS a server. Servers log. That's 91% noise.
Same pattern across all 5 repos. The console.log detector was designed for frontend/app code where you strip console output before shipping. For servers, CLIs, and libraries, it's the wrong signal entirely.
The fix: We made 3 detectors context-aware.
package.json. If the project has a bin field (CLI/server), the detector skips the project entirely.fixture/, example/, demo/, __mocks__/.Before the fix: ~72% noise. After: ~90%+ signal. The findings that remain are the ones that matter.
The lesson: A linter that outputs 500 findings where 457 don't matter is worse than useless. It trains people to ignore the output. Signal quality is the actual product.
vibecop serve exposes 3 MCP tools:
vibecop_scan: scan a directoryvibecop_check: check a single filevibecop_explain: explain what a detector catchesOne config block adds it to any MCP client:
{"mcpServers": {"vibecop": {"command": "npx", "args": ["vibecop", "serve"]}}}
Scored 100/100 on mcp-quality-gate compliance testing (10/10 tests passed). This extends vibecop from 7 agent tools (via vibecop init hooks) to 10+ by adding Continue.dev, Amazon Q, Zed, and anything else that speaks MCP.
npm install -g vibecop
vibecop scan .
vibecop serve # MCP server mode
GitHub: https://github.com/bhvbhushan/vibecop
Docs: https://bhvbhushan.github.io/vibecop/
Playground: https://vibecop-pg.bhvbhushan7.com/
For anyone building dev tools: how do you handle the signal-to-noise tradeoff? Do you err on the side of more findings (risk noise) or fewer findings (risk missed bugs)? Genuinely curious about the philosophy.