StackHawk alternative

A StackHawk alternative for MCP servers and Claude skills

StackHawk is one of the better dynamic application security testing (DAST) tools — its scanner stands up against your running API, crawls the routes, fires payloads at request parameters, and reports OWASP Top 10 findings against the live wire format. SkillAudit doesn't do any of that, because there's nothing for a DAST scanner to crawl on a Claude skill or an MCP server. The dangerous code is in the tool handlers, the attacker is the LLM's prompt context, and the install decision is pre-deploy. Different threat models, different scanners — and the one a team installing MCP servers actually needs is the second one.

TL;DR

StackHawk is a DAST scanner. It needs a running target with HTTP routes; it spiders, fuzzes parameters, and reports OWASP-shaped findings — XSS, SQL injection, broken auth, security headers, sensitive data in responses. That's the right model for a customer-facing REST or GraphQL API, and StackHawk is genuinely good at it. It's not the right model for a Claude skill or MCP server: most MCPs run over stdio (no HTTP surface to crawl), the threat is LLM-mediated content flowing into tool handlers (not a malformed query string), and the install decision happens before the server ever runs in your environment. SkillAudit reads the source — every server.tool(...) handler, every @app.tool function, every fetch(args.url) SSRF site — and grades the repo on the same six axes (security, permissions, credentials, maintenance, client compatibility, docs) before you claude plugin install. We've graded 101 of the most-installed MCP servers this way. 50% shipped SSRF, 38% had credential-handling findings, 19% earned an A. StackHawk in CD against your customer-facing API; SkillAudit in CI against the agent code that runs inside your trust boundary.

Why teams look for a StackHawk alternative for Claude skills and MCP servers

StackHawk is well-positioned for what it does — DAST in CD pipelines, scanning the running API after deploy to a staging environment, catching the regression where a refactor reintroduced an injection sink that static analysis missed. Teams that build customer-facing APIs and need a black-box runtime scanner alongside their SAST tools have good reasons to keep using it.

But ICP buyers and authors keep landing on three structural reasons DAST as a category — StackHawk included — doesn't fit the install decision for Claude skills and MCP servers:

Three buyer-side reasons we hear:

How SkillAudit is different

SkillAudit is a static + LLM-assisted scanner built specifically for the install-time decision on Claude skills and MCP servers. It reads the source — TypeScript, Python, Go, Rust, the nine languages that ship official MCP SDKs — and locates every server.tool(...) registration, every @app.tool decorator, every handler body, every fetch() call inside a handler. Then it runs the seven checks that compose into a single A–F grade:

Output is a single A–F grade plus a public report card at a stable URL with file paths and finding counts. Run time: roughly 60 seconds. It runs without standing up a target environment, without provisioning credentials, without a CD pipeline — paste a URL, get a graded report, decide whether to install.

Side by side

 StackHawkSkillAudit
Scanner typeDAST — runtime, black-box, requires a running targetStatic + LLM-assisted — reads source, no running server
Threat modelExternal web client probing HTTP / GraphQL / gRPC / SOAPLLM-mediated attacker via untrusted content flowing into tool handlers
Primary axisOWASP Top 10 against a deployed APISix-axis MCP rubric: security, permissions, credentials, maintenance, client compat, docs
What it readsLive HTTP responses from a running appSource files — every server.tool / @app.tool handler
stdio MCP serversCannot scan — no HTTP surface to crawlYes — reads source regardless of transport
HTTP / SSE MCP serversCould spider the JSON-RPC endpoint, but tools aren't enumerable as routesYes — reads tool registrations directly from source
SSRF in fetch(args.url) tool handlersCatchable only if you trick the LLM into calling the tool with a probe payload — post-installYes — pattern check fires statically; first-class axis
Command-exec in tool handlersSame — needs LLM-mediated invocation against a running serverYes — flags shell=True, execSync, os.system in handler bodies
Prompt-injection susceptibilityNot in scope — no model of the LLM-as-instruction-channel attackYes — Claude Haiku 4.5 red-teams every extracted handler
Credential echo from process.envCatchable only by the live response, if probed correctlyFirst-class axis; flags env vars on handler return paths
Maintenance / repo signalsNot in scopeLast commit, open issues, advisory feed; per-axis
Client compatibilityNot in scopeYes — non-standard transports + protocol-version mismatches
Setup before scanStand up target env, configure auth, define routes, manage secretsPaste a public GitHub URL — runs in 60s, no target needed
Public per-repo report cardNo — findings live in the StackHawk app, tied to your envYes — stable URL with file paths and finding counts
Embeddable badge for authorsNo public-facing badge modelYes — A–F badge updates per scan
PricingFree tier; paid plans by app/scan/seatFree: 3 audits/mo public · Pro $19/mo · Team $99/mo

The shape of the gap, in 30 seconds

The simplest way to see why DAST and MCP scanning aren't substitutes is to look at the canonical SSRF in an MCP tool handler:

// Common SSRF idiom in a Claude skill / MCP server.
// Clean under DAST (no HTTP surface to crawl on stdio).
// F-grade SSRF under SkillAudit (handler reads source).
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";

const server = new McpServer({ name: "fetch-helper", version: "1.0" });

server.tool(
  "fetch_url",
  "Fetch the contents of any URL",
  { url: z.string() },
  async ({ url }) => {
    const res = await fetch(url);                  // SSRF
    const body = await res.text();
    return { content: [{ type: "text", text: body }] };
  }
);
server.connect(new StdioServerTransport());

For a DAST tool to fire on this, three things have to be true: the server has to expose an HTTP listener (it doesn't — stdio), the scanner has to know which tool to call (it doesn't — tools aren't routes the spider can enumerate), and the scanner has to coax the LLM into invoking the tool with the probe URL (StackHawk doesn't model the agent loop). The same handler is a one-line static catch — a fetch() with an LLM-controlled argument inside a tool registration. SkillAudit reads it directly from source, files a finding, and the repo lands on the public board with the file path and a grade.

It's not that DAST is bad — it's that the gap between "running web app probed from outside" and "Claude skill installed into an agent's trust boundary" is wide enough that an entirely different class of scanner is needed. SkillAudit was built to fill that gap.

What the data says

We ran SkillAudit against 101 of the most-installed Claude skills and MCP servers — the full live board is public and growing. The corpus includes vendor-official releases (Stripe, PayPal, MongoDB, Redis, Cloudflare, AWS, Azure, GCP, Heroku, Notion, Snowflake, Pinecone, Couchbase, Auth0, Resend, Brave, Vectara, Meilisearch, plus Anthropic's nine official MCP language SDKs), popular indie frameworks (FastMCP, mcp-use, mcp-agent), and community releases.

Results: 50% (50/101) shipped SSRF findings, 38% (38/101) had credential-handling findings, 10% (10/101) had command-exec findings, only 19% (19/101) earned an A. Full grade distribution: 19 A · 30 C · 10 D · 42 F. Methodology and per-repo grades are in our research post: The state of MCP server security, 2026.

The relevant point for the StackHawk comparison: every one of those findings is in source code, in a tool handler, that DAST has no surface to reach. Most of the F-grade repos in the corpus run over stdio — there's literally nothing for a runtime scanner to crawl. A few serve over HTTP / SSE, but the JSON-RPC endpoint hides the tools behind tools/call arguments that DAST spiders can't enumerate. The threat surface MCP introduced is, by construction, a static-analysis problem.

When StackHawk is still right

StackHawk earns its keep on a different problem. Specifically:

The most useful framing: StackHawk runs against the public-facing app you ship; SkillAudit runs against the MCP servers and Claude skills you install. Different code, different threat models, different points in the SDLC. Run both, in different jobs, in different pipelines.

Workflow

Three steps to add SkillAudit on top of your existing DAST setup:

  1. Keep StackHawk in CD. If it's already gating your customer-facing API in staging, leave it alone. SkillAudit doesn't replace it; the threat surface is different.
  2. Add SkillAudit as a pre-install gate. Before claude plugin install, paste the URL into SkillAudit (or wire the GitHub Action — Pro plan) to gate adoption on a minimum grade. The first time most teams run this, they reject 30-50% of the MCPs they were planning to install. The grade tells you which.
  3. Treat SkillAudit and DAST as different jobs. StackHawk in your deploy stage against the running staging API; SkillAudit in a separate plugin-audit stage that runs whenever .claude/plugins.lock changes. The two never collide; they cover different code paths and different threat models.

Indie developers shipping MCP servers can run SkillAudit at zero cost — the free tier covers three audits a month on public repos, and the public report card is shareable on your README the same day you publish. Buyers gate adoption with the public grade; authors embed the badge to win listings.

Try SkillAudit on your repo — free

Paste any GitHub URL on the home page, get a graded report card in 60 seconds. Your repo joins the public board only if you opt in; private repos audit through a single-repo OAuth scope, never org-wide.

Audit my repo