Comparison
GitHub Code Scanning vs SkillAudit
GitHub Code Scanning runs CodeQL — a powerful SAST engine with a proven track record on conventional web application code. SkillAudit runs a focused scanner tuned for the threat surface MCP servers introduce. Both do static analysis. The difference is which sources and sinks each was written to model.
Quick verdict
- Choose GitHub Code Scanning if: you need zero-cost, GitHub-native SAST running CodeQL's standard query pack against all your source code — SQL injection, XSS, path traversal, hardcoded credentials, and other OWASP Top 10 patterns in conventional web app and API code. It's free for public repos and integrates in two clicks.
- Choose SkillAudit if: you want a scanner that models the threat surface MCP servers introduce — SSRF in
fetch(url)tool handlers where the LLM supplies the URL, prompt injection flowing through tool responses, credential echo fromprocess.envinto tool output, and permission scope bloat. These are the patterns CodeQL's standard pack wasn't written to model, and they're common in the wild. - Run both: GitHub Code Scanning catches the OWASP patterns that apply to any JavaScript codebase. SkillAudit catches the MCP-specific patterns on top. Both can run in CI and neither interferes with the other.
Same engine class, different rule packs
CodeQL and SkillAudit's static analysis engine are both doing taint-flow analysis — they follow untrusted data from a source (user input, network response, environment variable) to a dangerous sink (a fetch() call, a database query, a log statement). The key difference is which sources and sinks each tool's rule pack was written to recognize.
CodeQL's standard JavaScript and Python query packs were built around conventional web application patterns: HTTP request parameters flowing into SQL queries (SQL injection), URL parameters flowing into res.render() (XSS), user input flowing into child_process.exec() (command injection). These are the right sources and sinks for a web server or API.
An MCP server has a different source and sink topology:
- The source is the LLM's tool-call arguments — specifically, the
argsobject passed to a function body registered viaserver.tool('name', schema, handler). Thatargsobject comes from the model, which may have been influenced by untrusted content in an earlier tool response. CodeQL's JavaScript sources don't modelargsin an MCP SDK callback as an untrusted input — it's not an HTTP request parameter. - One important sink is the fetch call where the URL is derived from tool args —
fetch(args.url)orfetch(`${baseEndpoint}/${args.path}`). That's an SSRF sink when the LLM might supply an internal IP or a cloud-metadata address. CodeQL's standard SSRF query looks for sources flowing into HTTP clients in conventional server-request handlers; it doesn't know thatargsin an async tool callback is the dangerous source. - Another sink is the tool's return value when it includes env var contents. A handler that returns
{result: data, debug: {env: process.env}}is leaking all environment variables into the model's context. Data-flow fromprocess.envinto a return path in a tool callback isn't a category CodeQL's standard pack prioritizes.
This isn't a criticism of CodeQL — it's an observation that the standard rule pack was built before MCP existed. Custom CodeQL queries could cover some of these patterns, but writing, maintaining, and testing custom queries is non-trivial work that most teams don't invest in for a new tool-category threat model. SkillAudit ships pre-built rules for exactly this surface.
Side by side
| GitHub Code Scanning (CodeQL) | SkillAudit | |
|---|---|---|
| Underlying engine | CodeQL taint-flow analysis + standard query packs | AST-based static analysis + LLM-assisted behavioural probe |
| Source model | HTTP request parameters, URL params, form input, file uploads | MCP tool-call arguments (args from server.tool() handlers), untrusted tool responses |
| SSRF sink model | Generic URL fetch sinks; misses dynamic baseURL + template-string patterns in MCP handlers | MCP-specific: fetch(args.url), fetch(\`${endpoint}/…\`), configurable endpoint + caller-controlled path |
| Prompt-injection probe | No — static analysis cannot model LLM behavioural response to untrusted content in tool output | Yes — LLM-assisted: extracts tool handlers, red-teams them via Claude Haiku 4.5 for prompt-injection susceptibility |
| Credential-echo detection | Hardcoded-secrets query; doesn't model runtime process.env reads into tool return values | Traces process.env.X reads into async handler return paths as a first-class axis |
| Permission scope analysis | No | Yes — flags over-privileged OAuth/API scope declarations relative to tool functionality |
| Buyer-readable A–F grade | No — finding list in Security tab (private to repo) | Yes — single letter grade + public report card URL |
| Scans third-party repos | No — requires repo access | Yes — any public URL, no OAuth required |
| Public badge for authors | No | Yes — embeddable skill-grade badge for README and marketplace listings |
| Free for public repos | Yes — fully free on GitHub | Yes — 3 audits/month + unlimited public report card reads |
| Paid plan (private repos) | GitHub Advanced Security (enterprise pricing) | $19/mo Pro (unlimited), $99/mo Team (10 seats, SSO) |
| Custom rule support | Yes — write custom CodeQL queries (high effort) | Rule pack maintained by SkillAudit; community issue tracker for coverage requests |
The data: findings CodeQL's standard pack misses
We've audited 101 of the most-installed Claude skills and MCP servers and published every grade and finding publicly. 50 of 101 repos (50%) had SSRF findings, 38 had credential-handling findings (38%), and 42 earned an F grade. The grade distribution is 19 A · 30 C · 10 D · 42 F.
The repos that failed SkillAudit are not repos that CodeQL's standard JavaScript SAST pack has flagged. The SSRF pattern SkillAudit catches is template-string fetch with a configurable endpoint or handler-supplied URL — a pattern so common in MCP code that it appears in official SDK examples — but CodeQL's standard SSRF sources model HTTP request parameters, not MCP tool-call args.
Concrete example: heroku/heroku-mcp-server has GitHub Code Scanning enabled. It earned an F from SkillAudit. The 10 SSRF-primitive fetch(`${this.endpoint}/…`) call sites in its tool handlers are not in CodeQL's finding set because the MCP SDK callback isn't a recognized source in the standard JavaScript pack. Both scanners are correct — they're measuring different things. The Heroku team is patching the endpoint-construction pattern; the GHCS findings remain about other things.
Differentiator: the LLM-assisted prompt-injection probe
The most fundamental gap between CodeQL and SkillAudit is the prompt-injection probe. Prompt injection in MCP is a behavioural property: it asks "if this tool returns content that contains adversarial instructions, will a downstream LLM follow them?" That question requires running a model — there's no static dataflow query that can answer it because the dangerous property is about how an LLM interprets the content, not just what fields it flows through.
SkillAudit's probe extracts the return paths of registered tool handlers, constructs synthetic responses that include adversarial instruction payloads, and uses Claude Haiku 4.5 to evaluate whether the model would treat those instructions as authoritative. This is a class of analysis CodeQL cannot do by design — it's static, not model-behavioural. It's also the analysis most relevant to the real-world risks of agentic workflows in 2026, where chained tool calls across multiple community skills are the norm.
When GitHub Code Scanning is still the right choice
GitHub Code Scanning is the right foundation for any codebase. It catches things SkillAudit doesn't try to catch — SQL injection in database queries, XSS in rendered output, path traversal in file-system operations, and known-bad patterns in non-MCP code. If your repo contains conventional web app code alongside an MCP server, GHCS catches the web app vulnerabilities; SkillAudit catches the MCP server vulnerabilities. Keep both.
Specifically, GitHub Code Scanning is the better choice if:
- You write custom CodeQL queries and want to maintain MCP-specific rules yourself in the CodeQL ecosystem.
- Your codebase is polyglot and you need uniform SAST coverage across languages SkillAudit doesn't yet cover (Java, Go, Ruby, C++).
- GitHub Advanced Security's organizational secret scanning, dependency review, and audit log are requirements for your compliance posture.
For MCP-specific findings, SkillAudit's pre-built rule pack is the faster path. For everything else, GitHub Code Scanning with CodeQL is non-negotiable baseline hygiene.
Try SkillAudit on your repo — free
Paste any public GitHub URL. No sign-up for public audits. Your grade is returned in 60 seconds; the report card is private until you opt in to the public board.