Open
Conversation
Introduce MCP (Model Context Protocol) as a first-class ecosystem in guarddog. This adds the ECOSYSTEM.MCP enum value, config file discovery for 11 MCP clients (Claude Desktop, Claude Code, Cursor, VS Code, Windsurf, Cline, Roo Code, Continue, Codex, Gemini CLI, Copilot CLI), a normalized data model (MCPServerConfig / MCPConfigFile / MCPInventory), and two scanner classes: MCPConfigScanner (package scanner) and MCPDiscoveryScanner (project scanner). Discovery scopes recursive globs to known VS Code extension and config directories to avoid expensive walks over the entire home directory. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add 7 security rules for MCP configuration analysis: - inline-secret-in-mcp-config: hard-coded credentials in env/headers - plaintext-http-mcp: insecure HTTP endpoints - arbitrary-shell-launcher: shell wrapper execution (bash, sh, cmd, etc.) - shared-project-mcp-config: project-scoped configs shared via VCS - floating-package-launcher: unpinned npx/uvx/pipx/docker packages - dangerous-tool-surface: server names suggesting risky capabilities - overbroad-filesystem-access: broad paths (/, ~, .ssh, .aws) in args Register the rules in the metadata detector registry so they are available via 'guarddog mcp list-rules' and 'guarddog mcp scan'. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extend the Detector base class with optional help_url and verbose_description fields. The human-readable reporter now shows a 'ref:' link for each metadata finding, and a 'why:' explanation when --verbose is passed. The --verbose flag is threaded through all CLI scan/verify paths and all reporter interfaces. Also introduce _LazyRulesChoice in the CLI to defer metadata detector instantiation until rule names are actually needed. This prevents eager imports that triggered network requests (e.g. rubygems cache refresh) on every CLI invocation, even for unrelated ecosystems. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add 48 unit tests covering all 7 MCP metadata detectors, including positive detection, negative/safe cases, edge cases (placeholders, substrings, scoped paths), and the rule registry. Add 5 integration tests for MCPConfigScanner.scan_local() using temporary .mcp.json configs to verify end-to-end detection of inline secrets, plaintext HTTP, shell launchers, and benign configs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR Inspired by @AlecRandazzo thread: https://detection-response.slack.com/archives/C01TNGGQ84V/p1774018433400609
Summary
Add MCP (Model Context Protocol) as a first-class ecosystem in guarddog, enabling static security analysis of MCP server configurations across 11 AI coding clients.
MCP configs define how AI agents connect to external tool servers. Misconfigurations — hardcoded secrets, shell wrappers, unpinned packages, overbroad filesystem access — create real attack surface as MCP adoption grows across developer tooling. This PR adds discovery, parsing, and 7 metadata security rules to catch these issues.
What's included
MCP ecosystem plumbing
ECOSYSTEM.MCP = "mcp"enum value — automatically registers CLI subcommand (guarddog mcp scan,guarddog mcp verify,guarddog mcp list-rules)MCPConfigScanner(package scanner) andMCPDiscoveryScanner(project scanner).mcp.json,.cursor/mcp.json,.vscode/mcp.json, etc.) and user-scoped paths (~/Library/Application Support/Claude/,~/.codex/config.toml, etc.)$HOME11 client parsers
Normalized parsing for: Claude Desktop, Claude Code, Cursor, VS Code, Windsurf, Cline, Roo Code, Continue, Codex, Gemini CLI, Copilot CLI. Each parser handles the client's specific config format (JSON/YAML/TOML, varying key names like
mcpServersvsserversvsmcp_servers) and produces a uniformMCPServerConfig→MCPConfigFile→MCPInventorymodel.7 metadata security rules
Rule | What it catches -- | -- inline-secret-in-mcp-config | Hard-coded API keys, tokens, passwords in env vars or headers plaintext-http-mcp | MCP server endpoints using http:// instead of https:// arbitrary-shell-launcher | Servers launched via bash -c, sh -c, cmd /c, etc. shared-project-mcp-config | Project-scoped configs (.mcp.json, .cursor/mcp.json) likely committed to VCS floating-package-launcher | Unpinned npx, uvx, pipx, or docker :latest package resolution dangerous-tool-surface | Server names/commands suggesting exec, delete, ssh, kubectl, etc. overbroad-filesystem-access | Broad or sensitive paths (/, ~, .ssh, .aws) in server args or cwd--verboseflag and finding citations (cross-ecosystem)Detectorbase class gains optionalhelp_urlandverbose_descriptionfieldsref:link for each metadata finding--verboseadds awhy:explanation with remediation guidancehelp_url/verbose_descriptionincrementallyLazy rule loading (cross-ecosystem perf fix)
matchcase)_LazyRulesChoicein the CLI defers rule set computation until Click actually needs tab-completion or validationTests
MCPConfigScanner.scan_local()with temporary.mcp.jsonconfigsExample output
With
--verbose, each finding also shows awhy:line with a detailed explanation and remediation guidance.Commits
Test plan
python -m pytest tests/analyzer/metadata/test_mcp_detectors.py -v— 48 detector unit testspython -m pytest tests/core/test_mcp_config_scanner.py -v— 5 integration testspython -m guarddog mcp list-rules— lists all 7 metadata rules + 1 source code rulepython -m guarddog mcp scan <dir>— scans a directory and reports findings withref:linkspython -m guarddog mcp scan <dir> --verbose— includeswhy:explanationspython -m guarddog pypi scan requests— verify existing ecosystems unaffectedmake test— full suite (no new failures introduced)