shipsafe-mcp
OfficialScans Android app configurations for security issues like debuggable builds, cleartext traffic, and permissive WebViews.
Scans Django applications for exposed secrets, injection, missing authentication, and other server-side vulnerabilities.
Scans Expo and React Native apps for mobile security issues like tokens stored insecurely, permissive WebViews, and misconfigured app manifests.
Scans Express applications for missing authentication, IDOR, injection, SSRF, and other server-side vulnerabilities.
Scans FastAPI applications for missing authentication, injection, and other server-side vulnerabilities.
Scans Fastify applications for unprotected API routes, injection, and other server-side vulnerabilities.
Checks Firebase projects for open Firestore/Realtime Database rules, test-mode rules, and unsafe use of service_role credentials.
Scans Flask applications for injection, SSRF, missing authentication, and other server-side vulnerabilities.
Scans Hono applications for unprotected API routes, injection, and other server-side vulnerabilities.
Scans iOS app configurations for security issues like disabled App Transport Security and other mobile misconfigurations.
Detects MongoDB operator injection and other insecure database query patterns.
Scans Next.js applications for security issues such as exposed secrets, missing auth in API routes and server actions, and unsafe client-side data access.
Checks npm dependencies for hallucinated packages, typosquats, brand-new packages, and known CVEs with upgrade guidance.
Scans OpenAI integrations for leaked API keys, browser-side LLM calls, and AI endpoints without auth or rate limits.
Checks PyPI dependencies for hallucinated packages, typosquats, brand-new packages, and known CVEs with upgrade guidance.
Scans React applications for client-side security issues like leaked API keys, unsafe dangerouslySetInnerHTML usage, and secrets hardcoded in components.
Checks Stripe integrations for unverified webhook signatures, trusting client-supplied prices, and other payment security mistakes.
Checks Supabase projects for missing Row Level Security, insecure policies, public storage buckets, exposed service_role keys, and publicly readable tables.
Scans projects using the Vercel AI SDK for common AI security mistakes such as browser-side LLM calls and missing auth or rate limits.
Scans Vite projects for secrets exposed through VITE_ environment variables and other front-end security misconfigurations.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@shipsafe-mcpCan you scan my app for security issues and fix what you find?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
π‘οΈ ShipSafe
Find the security holes your AI coding assistant just shipped, before someone else does.
ShipSafe is an MCP server and CLI that checks AI-built ("vibe-coded") web and mobile apps for the mistakes that keep leaking data: API keys in the browser bundle, Supabase tables without Row Level Security, Firebase rules left in test mode, API routes anyone can call, unverified Stripe webhooks, AI endpoints that can drain your credits, and npm packages the model made up.
It plugs into Claude Code, Cursor, VS Code, Windsurf and Claude Desktop. Your assistant scans the project, explains each problem in plain language, fixes it, and re-scans to confirm.
What it looks like
A typical conversation in Claude Code or Cursor:
You: Is my app safe to launch?
Assistant: I ran ShipSafe on your project. Launch readiness: 0/100 (F), do not ship yet. Six issues can be exploited by anyone on the internet:
Your OpenAI key is public.
NEXT_PUBLIC_OPENAI_API_KEYis baked into the JavaScript every visitor downloads, so anyone can copy it and run up your bill.Anyone can read and delete your
poststable. It was created without Row Level Security, and your anon key ships with the site.Anyone can fake a payment.
/api/webhooktrustscheckout.session.completedevents without checking Stripe's signature.β¦
Should I fix these, starting with the most severe?
After the fixes, the assistant calls verify_fixes, which returns what was fixed, what is still open, and anything new the edits introduced:
The same scan works from the terminal and in CI:
All screenshots are real output from scanning the intentionally vulnerable demo app in tests/fixtures/nextjs-supabase. Keys are shown redacted, exactly as ShipSafe prints them.
Related MCP server: Security-Use MCP Server
Install
ShipSafe runs with uv (uvx), so there is nothing to install globally. Python 3.10+ is fetched automatically if you don't have it.
Claude Code
claude mcp add shipsafe -- uvx shipsafe-mcpCursor: click the badge above, or add to ~/.cursor/mcp.json:
{ "mcpServers": { "shipsafe": { "command": "uvx", "args": ["shipsafe-mcp"] } } }VS Code (Copilot agent mode): click the badge above, or add to .vscode/mcp.json:
{ "servers": { "shipsafe": { "command": "uvx", "args": ["shipsafe-mcp"] } } }Windsurf (~/.codeium/windsurf/mcp_config.json) and Claude Desktop (claude_desktop_config.json) use the same mcpServers block as Cursor. Claude Desktop may need the absolute path to uvx (which uvx / where uvx).
Before the PyPI release, install straight from GitHub:
claude mcp add shipsafe -- uvx --from git+https://github.com/EthYusuf/shipsafe shipsafe-mcpThen ask your assistant: "Run a ShipSafe pre-launch audit", or use the pre-launch-audit prompt.
What it catches
68 rules, written for the stacks AI tools actually generate: Next.js, React/Vite, Expo/React Native, Express/Hono/Fastify, Supabase, Firebase, Stripe, OpenAI/Anthropic/Vercel AI SDK, Flask/Django/FastAPI.
Area | Examples |
π Leaked secrets | Keys behind |
ποΈ Supabase & Firebase | Tables without RLS, |
πͺ Access control | Route handlers, Pages API routes, Express routes and server actions with no auth check; IDOR, where the user id comes from the request body instead of the session; |
π Injection | SQL built with template strings, Supabase |
π³ Payments | Stripe webhooks without |
π€ AI apps | LLM calls from the browser ( |
π± Mobile | Tokens in AsyncStorage/localStorage, permissive WebViews, |
π¦ Supply chain | Hallucinated packages that don't exist on npm/PyPI (slopsquatting), typosquats, packages published days ago, known CVEs via OSV.dev with the right upgrade version |
π Live site (opt-in) | Downloadable |
The full list with explanations is in docs/rules.md.
MCP tools
Tool | What it does |
| Scans the project and returns a launch-readiness score, a verdict and the top findings in plain language |
| Pages through findings, filtered by severity, category or file |
| Full detail for one finding: impact, fix, redacted code context, and a ready-made fix prompt |
| Re-scans and reports what was fixed, what's new and how the score changed |
| Checks code before it is written to disk; the assistant can call it on auth, payment and database code |
| Hallucinated, typosquatted, brand-new and vulnerable dependencies |
| Passive checks against a deployment you own (localhost is always allowed) |
| Writes an HTML, Markdown, SARIF or JSON report to |
Also available: the prompts pre-launch-audit and secure-feature, and the resources shipsafe://rules and shipsafe://report/latest.
CLI and CI
uvx --from shipsafe-mcp shipsafe scan . # colored terminal report
uvx --from shipsafe-mcp shipsafe scan . --format html -o report.html
uvx --from shipsafe-mcp shipsafe scan . --fail-on high # exit 1 for CI
uvx --from shipsafe-mcp shipsafe probe http://localhost:3000 # live checks
uvx --from shipsafe-mcp shipsafe rulesGitHub Actions posts results to code scanning and to the job summary:
permissions:
contents: read
security-events: write
steps:
- uses: actions/checkout@v4
- uses: EthYusuf/shipsafe@v0.1.0
with:
fail-on: highpre-commit:
repos:
- repo: https://github.com/EthYusuf/shipsafe
rev: v0.1.0
hooks:
- id: shipsafeConfiguration
Silence a single line, optionally for one rule only:
const demoKey = "sk_test_β¦"; // shipsafe-ignore: secret.hardcodedOr add .shipsafe.yml at the project root:
ignore_paths: ["scripts/", "**/*.stories.tsx"]
disable_rules: [config.missing-security-headers]
severity_overrides:
supabase.public-bucket: infoSafety and privacy
A security tool must not become a leak itself.
No code is executed. JavaScript and TypeScript are parsed with tree-sitter and Python with
ast. Nothing is imported, run or installed.Secrets are always redacted in everything ShipSafe outputs (
sk-proj-****1Cx7), so raw keys never reach your AI provider's logs. The test suite checks this for every output format.Network access is limited and optional. Dependency checks call registry.npmjs.org, pypi.org and api.osv.dev with package names and versions only.
--offline/offline: trueturns them off.Live probes only send plain GET requests. They run against localhost by default. Any other host needs your explicit confirmation (the MCP server asks you directly when your client supports it) or
SHIPSAFE_PROBE_ALLOWLIST. Row data read from Supabase or Firebase is never returned, only table and column names.No telemetry.
Accuracy, honestly
ShipSafe is a heuristic static analyzer. It finds likely issues fast, and it is not a penetration test.
Labeled corpus.
benchmarks/run.pyscans realistic vulnerable apps (Next.js + Supabase, Expo + Firebase, Express + MongoDB, Flask) plus a correctly built app. Every labeled issue is found, the clean app scores 99/A, and a typical scan takes ~50β300 ms offline. We wrote this corpus ourselves, so treat it as a regression suite, not proof of real-world accuracy.Real projects. Before release we ran ShipSafe on popular open-source apps and fixed every false positive we found. For example, the official Vercel Supabase + Stripe starter scores 93/A, and its remaining findings match what Supabase's own database linter reports.
Known limits. Taint tracking stays within a function (plus variable aliases), not across files. Authorization is inferred from common patterns (
auth(),getUser(), middlewareβ¦), so custom auth wrappers may need ashipsafe-ignore. Native Swift/Kotlin/Dart source is not analyzed; manifests and configs are.
Found a false positive or a miss? Please open an issue with a minimal snippet. Every fix gets a regression test.
Development
git clone https://github.com/EthYusuf/shipsafe && cd shipsafe
uv sync
uv run pytest # full test suite, including an in-process MCP client
uv run ruff check src tests
uv run python benchmarks/run.pySee CONTRIBUTING.md for how rules are structured and how to add one.
License
MIT
Available Tools
8 toolscheck_dependenciesARead-onlyIdempotent
Check direct npm/PyPI dependencies for hallucinated (non-existent) packages, typosquats, suspiciously new packages and known vulnerabilities (OSV.dev).
Args: path: Project root. Defaults to the client's workspace root.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already cover read-only, idempotent, non-destructive behavior. The description adds useful behavioral context beyond that by naming the specific checks performed, the OSV.dev data source, and the 'direct dependencies' scope, which clarifies that transitive dependencies are not the focus. No contradiction with annotations exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is tight and front-loaded: the opening sentence states the purpose and scope, followed by a minimal Args block. There is no filler or repetition of schema details, and every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With a single optional parameter, rich annotations, and an output schema available, the description covers everything needed for correct invocation. It explains what the tool checks, the dependency scope, and the path semantics without over-explaining return values that the output schema already documents.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must clarify the only parameter, path. It does: 'Project root. Defaults to the client's workspace root.' This resolves the schema's opaque default null and gives the agent enough semantic grounding to invoke the tool correctly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('check') and resource ('direct npm/PyPI dependencies'), and enumerates the exact threat categories it covers: hallucinated packages, typosquats, suspiciously new packages, and known vulnerabilities via OSV.dev. This scope clearly differentiates it from broader siblings like scan_project without needing to inspect them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage context via 'direct npm/PyPI dependencies' and the optional path argument, but it never explicitly states when to prefer this tool over siblings like scan_project or scan_snippet. There are no exclusions or alternative routing guidance, so the agent must infer applicability from the scope wording alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
generate_reportAIdempotent
Write a shareable report for the latest scan.
The HTML report has a score ring, severity filters and a "copy fix prompt" button per finding. By default it is written to /.shipsafe/ (which is git-ignored automatically).
Args: format: html, md (Markdown), sarif (GitHub code scanning) or json. path: Project root; defaults to the most recently scanned project. output: Explicit output file path.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | ||
| format | No | html | |
| output | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide idempotentHint=true, readOnlyHint=false, and destructiveHint=false, so the agent already knows it writes but is safe to call repeatedly. The description adds useful context beyond those: it states the default output location (<project>/.shipsafe/) and that it is automatically git-ignored, plus describes the HTML report's interactive features. It does not describe error cases (e.g., missing scan) but does not contradict annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and well-structured: purpose sentence, a bullet on HTML report features, a note on default location, then a concise 'Args' list. It is front-loaded with the primary action, and every sentence adds value. No fluff or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a report generation tool, the description covers the core behavior (what it writes, where it writes, available formats) and the output schema exists to describe the return value. It does not explicitly mention prerequisites (e.g., that a scan must have been run) but the phrase 'for the latest scan' plus the sibling scan_project makes that inference reasonable. Missing details like error handling are minor given the output schema and the tool's straightforward nature.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry the full parameter explanation. It does: it explains each argument ('format' with enumerated values and their meaning, 'path' as project root with a default, 'output' as an explicit file path). This adds meaning far beyond the bare schema types and defaults, fully compensating for the lack of schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a clear verb+resource: 'Write a shareable report for the latest scan.' It specifies the output artifact and its key features (score ring, severity filters, copy-fix button), and the sibling context (scan_project, list_findings, etc.) shows this tool is distinct because it generates a report rather than performing analysis. The purpose is unambiguous and not a tautology.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies it should be used after a scan by saying 'for the latest scan,' but it does not explicitly state when to use it versus alternatives, nor does it list any exclusions (e.g., 'use list_findings for raw findings'). It does explain the format options and defaults, which helps the agent decide, but lacks explicit routing or when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_findingARead-onlyIdempotent
Full details for one finding: impact, fix guidance, code context and references.
Args: finding_id: The id from scan_project / list_findings (e.g. "SS-3F9A2C1").
| Name | Required | Description | Default |
|---|---|---|---|
| finding_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds little behavioral detail beyond the purpose statement; 'full details' describes the output rather than disclosing behaviors such as auth requirements, errors, or pagination. There is no contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no wasted words. The purpose is front-loaded, and the only parameter is documented in a compact, scannable format.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-parameter getter with an output schema and read-only annotations, the description covers the one missing invocation detail: where to obtain finding_id and what format it takes. Nothing else is required for an agent to call the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries full responsibility for parameter meaning. It defines finding_id as the ID from scan_project / list_findings and provides a concrete example format (SS-3F9A2C1), which is exactly what an agent needs to supply the required parameter correctly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: retrieving full details for one finding, and enumerates content categories (impact, fix guidance, code context, references). It clearly distinguishes itself from sibling list-oriented tools by emphasizing 'one finding' and by referencing scan_project / list_findings as the source of the ID.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear usage context by noting that finding_id comes from scan_project / list_findings, implying the tool is used after those tools. It does not explicitly list exclusions or alternatives, but the singular scope and the referenced parent tools make the intended workflow clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_findingsARead-onlyIdempotent
List findings from the latest scan, optionally filtered.
Args: severity: Only this severity (critical, high, medium, low, info). category: e.g. secrets, access-control, injection, backend-config, payments, ai, mobile, supply-chain. file: Substring of the file path. offset: Pagination offset. limit: Page size (max 100). path: Project root; defaults to the most recently scanned project.
| Name | Required | Description | Default |
|---|---|---|---|
| file | No | ||
| path | No | ||
| limit | No | ||
| offset | No | ||
| category | No | ||
| severity | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, so safety is covered. The description adds valuable behavioral context: the operation applies to the latest scan, path defaults to the most recently scanned project, limit is capped at 100, and offset/limit control pagination. This goes beyond what the annotations and schema alone convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and to the point. The one-line summary is front-loaded, followed by an Args block that is easy to scan. Every line adds useful information with no filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only listing tool with an output schema and six optional parameters, the description covers all invocation-critical details such as defaults, pagination, and filter formats. It only lacks explicit sibling-tool routing and ordering/sorting behavior, but those are not essential for a correct call.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the full burden, and it delivers. Every parameter is explained: severity enum values are listed, category gets examples, file is described as a substring, and offset/limit/path defaults are clarified. This compensates completely for the empty schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a clear verb and resource: 'List findings from the latest scan, optionally filtered.' This is specific and understandable. However, it does not explicitly differentiate itself from siblings like get_finding or scan_project, relying mostly on the tool name and list semantics to do that.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to choose this tool over get_finding, scan_project, or generate_report. The mention of 'latest scan' and 'path defaults to the most recently scanned project' offers context but not active routing or exclusions. An agent would have to infer use cases from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
probe_liveARead-onlyIdempotent
Passively check a running deployment: exposed .env/.git, secrets in JS bundles, Supabase tables readable with the public anon key, open Firebase Realtime Database, CORS, cookies, security headers.
Only plain GET requests are made. localhost is always allowed. For any other host the user must confirm ownership (ShipSafe asks them directly when the client supports it). Set authorized=true ONLY after the user has explicitly said they own the site.
Args: url: Site to check, e.g. http://localhost:3000 or https://myapp.vercel.app authorized: The user explicitly confirmed they own / may test this site.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | ||
| authorized | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds substantial behavioral detail beyond the annotations: only plain GET requests are made, localhost is always allowed, other hosts require user ownership confirmation, and the authorized flag must only be set after explicit confirmation. This meaningfully informs the agent about safety and consent requirements, and it does not contradict the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and front-loaded with the core purpose, followed by safety/authorization rules and parameter explanations. There is minor redundancy between the 'authorized' explanation in the prose and the Args section, but overall it is efficient and readable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers purpose, scope, request behavior, ownership authorization, and parameter semantics. With an output schema present and safety annotations already declaring read-only/idempotent/non-destructive behavior, nothing essential is missing for an agent to correctly invoke the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the full burden for parameters. It explains url with concrete examples and explains authorized as requiring explicit user confirmation of ownership or permission, which adds real semantic value beyond the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: passively checking a running deployment for a specific list of issues (secrets, exposed files, open databases, CORS, cookies, headers). The verb 'check' plus the explicit resource and scope distinguishes it from sibling tools like scan_project or scan_snippet.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides strong context for when to use the tool: against a running deployment, using only plain GET requests, and with explicit ownership confirmation for non-localhost hosts. It does not explicitly name alternatives or say when not to use this tool, but the passive-deployment framing makes the intended use clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
scan_projectARead-onlyIdempotent
Scan a web or mobile app project for security issues and return a launch-readiness score.
Detects leaked secrets (public env vars, keys in client bundles), Supabase tables without RLS, open Firebase rules, API routes/server actions without auth, IDOR, SQL/NoSQL/command injection, SSRF, unverified Stripe webhooks, client-controlled prices, AI endpoints without auth or rate limits, insecure mobile config, and hallucinated/typosquatted/vulnerable dependencies.
Args: path: Absolute path to the project root. Defaults to the client's workspace root. check_dependencies: Look up dependencies on npm/PyPI and OSV.dev. offline: Never touch the network (skips registry and vulnerability lookups).
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | ||
| offline | No | ||
| check_dependencies | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already communicate read-only, idempotent, open-world, and non-destructive behavior. The description adds useful context beyond those annotations by explaining that dependency lookups happen by default, that offline mode skips network access and registry/vulnerability lookups, and that the scan returns a launch-readiness score.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is somewhat long because of the comprehensive vulnerability list, but that list earns its place by defining the tool's exact scope. The structure is clear: action, detection scope, then parameter documentation. It is front-loaded and not padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex scanner with an output schema, the description sufficiently covers the input parameters, defaults, network behavior, scope, and high-level return value. The annotations cover the read-only and non-destructive profile, so the description is complete enough for an agent to select and invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 0% description coverage, so the description carries the full burden for parameter meaning. It explains each parameter clearly: path is an absolute project root defaulting to the client workspace root, check_dependencies enables npm/PyPI/OSV.dev lookups, and offline disables network access. This fully compensates for the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific action ('Scan'), a specific resource ('a web or mobile app project'), and a concrete outcome ('return a launch-readiness score'). It also enumerates a detailed set of checks, which clearly distinguishes this project-wide scanner from siblings like scan_snippet.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The intended scope is implied by the first sentence and the coverage list, so an agent can infer it is for project-level security review. However, it never explicitly says when to use this tool versus scan_snippet, list_findings, check_dependencies, or generate_report, and it provides no 'when not to use' guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
scan_snippetARead-onlyIdempotent
Check a piece of code before writing it to disk (no project needed).
Use it for auth, payment, database, file/URL handling and AI-calling code.
Args: code: Source code to check. filename: Realistic path; it drives language and context detection (e.g. app/api/users/route.ts, components/Form.tsx, supabase/migrations/001.sql, app.py). runtime: Where the code runs. "client" = shipped to browsers/apps; "auto" guesses from filename/directives.
| Name | Required | Description | Default |
|---|---|---|---|
| code | Yes | ||
| runtime | No | auto | |
| filename | No | snippet.ts |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so the safety profile is covered. The description adds genuinely useful behavioral context: filename 'drives language and context detection', and runtime 'auto' guesses from filename/directives. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the purpose, then uses a clean Args structure. Every sentence earns its place, and the filename examples are compact yet illustrative.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a snippet-checking tool with an output schema and read-only annotations, the description covers invocation context fully: what input to provide, how filename affects behavior, and how runtime is determined. Nothing essential is missing for an agent to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description fully compensates. It explains code, gives filename semantics with realistic examples, and clarifies runtime values ('client' = shipped to browsers/apps; 'auto' guesses). The only minor gap is not explicitly defining 'server', but it is inferable from the enum and the contrast with 'client'.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Check a piece of code before writing it to disk'. It also clarifies scope with '(no project needed)' and lists concrete use cases (auth, payment, database, file/URL handling, AI-calling code), which distinguishes it from the sibling scan_project.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear positive guidance on when to use the tool ('Use it for auth, payment, database, file/URL handling and AI-calling code') and states it needs no project. It does not explicitly name scan_project as the alternative or provide an exclusion condition, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
verify_fixesARead-onlyIdempotent
Re-scan the project after edits and report what was fixed, what remains and the score change.
Args: path: Project root; defaults to the most recently scanned project.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior, so the description doesn't need to restate safety. It adds that a fresh re-scan is performed and results are reported as a delta, but it doesn't discuss side effects, cost, or prerequisites; the annotations carry the main behavioral burden.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences plus a single parameter note, with the main purpose front-loaded and no filler. Every sentence adds useful information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-optional-parameter tool with rich safety annotations and an output schema, the description is complete. It covers when to run it, what it reports, and the parameter's default, leaving no obvious gap in the call contract.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With no schema descriptions on the path parameter, the description fully compensates by defining path as 'Project root' and documenting its default behavior ('defaults to the most recently scanned project'). This is exactly the semantic information an agent needs and goes well beyond the schema's default null.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource: 'Re-scan the project after edits' and specifies the report contents ('what was fixed, what remains and the score change'). This makes the tool's purpose concrete and differentiates it from initial scans like scan_project and from passive listing tools like list_findings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives an explicit trigger: use after edits to verify that fixes took effect. It doesn't name sibling tools as alternatives or exclusions, but the 'after edits' context is clear enough that an agent won't confuse this with initial scanning or finding-listing tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
8 tool updates
v0.1.0- First observed
check_dependencies - First observed
generate_report - First observed
get_finding - First observed
list_findings - First observed
probe_live - First observed
scan_project - First observed
scan_snippet - First observed
verify_fixes
TDQS
Scored across 8 tools
Each tool has a clear primary purpose: scanning project/snippet/live, listing/getting findings, verifying fixes, checking dependencies, and generating reports. Minor overlap exists between scan_project and check_dependencies (and verify_fixes re-scans), but descriptions are specific enough to avoid serious misselection.
All tool names follow a consistent verb_noun pattern in lowercase snake_case: scan_project, list_findings, get_finding, verify_fixes, scan_snippet, check_dependencies, probe_live, generate_report. There are no mixed conventions or vague verbs.
Eight tools is well-scoped for a security scanning server. Each tool covers a distinct stage of the workflow: scanning, inspecting findings, verifying fixes, live probing, dependency checks, and reporting, with no redundant or unnecessary additions.
Core coverage is solid: scanning (project, snippet, live, dependencies), finding inspection (list, get), verification, and reporting. Minor gaps include the inability to dismiss/mark findings as false positives or view scan history, but these are not critical to the primary launch-readiness workflow.
Maintenance
Related MCP Connectors
Scan, monitor and fix a live web app from your editor: graded security reports with fix prompts.
Security reviews for coding agents: diffs checked against your org policy and live infrastructure.
Deep security scans of repos you own from your editor: dependency CVEs, SAST, git-history secrets.
Pay-per-call cybersecurity for AI agents: vuln scans, threat intel, compliance, code security.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceAutomatically detects security vulnerabilities in AI-generated code, scanning for hardcoded secrets, injection flaws, XSS, weak cryptography, authentication issues, path traversal, and vulnerable dependencies across JavaScript, Python, Java, and Go.19 npm2MIT
- AlicenseAqualityDmaintenanceEnables AI assistants to scan project dependencies and Infrastructure as Code files for security vulnerabilities and misconfigurations. It also provides automated fixing capabilities to remediate identified security issues.183MIT
- AlicenseAqualityDmaintenanceEnables AI coding agents to scan smart contracts and code for vulnerabilities, check against 12 famous-hack patterns, and return public security receipts directly in the IDE.45 npmMIT
- AlicenseNot gradedqualityFmaintenancePredeploy security scanner for AI-generated code. 80+ vulnerability patterns across secrets, auth, injection, config, Supabase, and logging. Runs locally, code never leaves your machine. Optional x402 witnessed attestation.44 npmApache 2.0