npm prodlint-mcpstdioMITupdated 9d ago
Production readiness for vibe-coded apps.
What can you do with prodlint?
prodlint
Production readiness for vibe-coded apps.
Static analysis for vibe-coded apps. Flags the security, reliability, performance, and AI quality issues that Cursor, v0, Bolt, and Copilot create โ hallucinated imports, missing auth, hardcoded secrets, unvalidated server actions, and more. Zero config, no LLM, 52 rules.
npx prodlint
prodlint v0.10.0
Scanned 148 files ยท 2 critical ยท 5 warnings ยท 1 info
src/app/api/checkout/route.ts
12:1 INFO No rate limiting โ anyone could spam this endpoint and run up your API costs rate-limiting
28:5 WARN Empty catch block silently swallows error shallow-catch
src/actions/submit.ts
5:3 CRIT Server action uses formData without validation next-server-action-validation
โณ Validate with Zod: const data = schema.safeParse(Object.fromEntries(formData))
src/lib/db.ts
1:1 CRIT Package "drizzle-orm" is imported but not in package.json hallucinated-imports
Scores
security 72 โโโโโโโโโโโโโโโโโโโโ (8 issues)
reliability 85 โโโโโโโโโโโโโโโโโโโโ (4 issues)
performance 95 โโโโโโโโโโโโโโโโโโโโ (1 issue)
ai-quality 90 โโโโโโโโโโโโโโโโโโโโ (3 issues)
Overall: 82/100 (weighted)
2 critical ยท 5 warnings ยท 4 info
Why?
Vibe coding is the fastest way to build. Shipping fast means knowing your code is production-ready โ not just that it compiles. Hardcoded secrets, hallucinated packages, missing auth, and XSS vectors pass type-checks and look correct โ but they aren't ready for production.
prodlint checks what TypeScript and ESLint don't: whether your vibe-coded app is ready for production.
Install
npx prodlint # Run directly (no install)
npx prodlint ./my-app # Scan specific path
npx prodlint --json # JSON output for CI
npx prodlint --sarif # SARIF 2.1.0 for GitHub Code Scanning
npx prodlint --summary # Quick pass/fail + top 3 blockers
npx prodlint --profile startup # Only critical findings
npx prodlint --profile strict # All findings including info
npx prodlint --baseline .prodlint-baseline.json # Only new findings
npx prodlint --ignore "*.test.ts" # Ignore patterns
npx prodlint --min-severity warning # Only warnings and criticals
npx prodlint --quiet # Suppress badge output
Or install it:
npm i -D prodlint # Project dependency
npm i -g prodlint # Global install
52 Rules across 4 Categories
Security (27 rules)
| Rule | What it checks |
|---|---|
secrets |
API keys, tokens, passwords hardcoded in source |
auth-checks |
API routes with no authentication |
env-exposure |
NEXT_PUBLIC_ on server-only secrets |
input-validation |
Request body used without validation |
cors-config |
Access-Control-Allow-Origin: *, wildcard + credentials escalated to critical |
unsafe-html |
dangerouslySetInnerHTML with user data |
sql-injection |
String-interpolated SQL queries (ORM-aware) |
open-redirect |
User input passed to redirect() |
rate-limiting |
API routes with no rate limiter |
phantom-dependency |
Packages in node_modules but missing from package.json |
insecure-cookie |
Session cookies missing httpOnly/secure/sameSite |
leaked-env-in-logs |
process.env.* inside console.log calls |
insecure-random |
Math.random() used for tokens, secrets, or session IDs |
next-server-action-validation |
Server actions using formData without Zod/schema validation |
env-fallback-secret |
Security-sensitive env vars with hardcoded fallback values |
verbose-error-response |
Error stack traces or messages leaked in API responses |
missing-webhook-verification |
Webhook routes without signature verification |
server-action-auth |
Server actions with mutations but no auth check |
eval-injection |
eval(), new Function(), dynamic code execution |
next-public-sensitive |
NEXT_PUBLIC_ prefix on secret env vars |
ssrf-risk |
User-controlled URLs passed to fetch in server code |
path-traversal |
File system operations with unsanitized user input |
unsafe-file-upload |
File upload handlers without type or size validation |
supabase-missing-rls |
CREATE TABLE in migrations without enabling RLS |
deprecated-oauth-flow |
OAuth Implicit Grant (response_type=token) |
jwt-no-expiry |
JWT tokens signed without an expiration |
client-side-auth-only |
Password comparisons or auth logic in client components |
Reliability (11 rules)
| Rule | What it checks |
|---|---|
hallucinated-imports |
Imports of packages not in package.json |
error-handling |
Async operations without try/catch |
unhandled-promise |
Floating promises with no await or .catch |
shallow-catch |
Empty catch blocks that swallow errors |
missing-loading-state |
Client components that fetch without a loading state |
missing-error-boundary |
Route layouts without a matching error.tsx |
missing-transaction |
Multiple Prisma writes without $transaction |
redirect-in-try-catch |
redirect() inside try/catch โ Next.js redirect throws, catch swallows it |
missing-revalidation |
Server actions with DB mutations but no revalidatePath |
missing-useeffect-cleanup |
useEffect with subscriptions/timers but no cleanup return |
hydration-mismatch |
window/Date.now()/Math.random() in server component render path |
Performance (6 rules)
| Rule | What it checks |
|---|---|
no-sync-fs |
readFileSync in API routes |
no-n-plus-one |
Database calls inside loops |
no-unbounded-query |
.findMany() / .select('*') with no limit |
no-dynamic-import-loop |
import() inside loops |
server-component-fetch-self |
Server components fetching their own API routes |
missing-abort-controller |
Fetch/axios calls without timeout or AbortController |
AI Quality (8 rules)
| Rule | What it checks |
|---|---|
ai-smells |
any types, console.log, TODO comments piling up |
placeholder-content |
Lorem ipsum, example emails, "your-api-key-here" left in production code |
hallucinated-api |
.flatten(), .contains(), .substr() โ methods AI invents |
stale-fallback |
localhost:3000 hardcoded in production code |
comprehension-debt |
Functions over 80 lines, deep nesting, too many parameters |
codebase-consistency |
Mixed naming conventions across the project |
dead-exports |
Exported functions that nothing imports |
use-client-overuse |
"use client" on files that don't use any client-side APIs |
Smart Detection
prodlint avoids common false positives:
- AST parsing โ Babel-based analysis for 12 rules (imports, catch blocks, redirects, SSRF, path traversal, JWT, HTML injection, hydration, transactions, env leaks, loops, SQL) with regex fallback
- Monorepo support โ npm/yarn/pnpm workspace dependencies resolved automatically
- Framework awareness โ Prisma, Drizzle, Supabase, Knex, and Sequelize whitelists prevent false SQL injection flags
- Middleware detection โ Clerk, NextAuth, Supabase middleware detected โ auth findings downgraded
- Block comment awareness โ patterns inside
/* */are ignored - Path alias support โ
@/,~/, and tsconfig paths aren't flagged as hallucinated imports - Route exemptions โ auth, webhook, health, and cron routes are exempt from auth/rate-limit checks
- Test/script file awareness โ lower severity for non-production files
- Fix suggestions โ findings include actionable
fixhints with remediation code
Scoring
Each category starts at 100. Deductions per finding:
| Severity | Deduction | Per-rule cap |
|---|---|---|
| critical | -8 | max 1 |
| warning | -2 | max 2 |
| info | -0.5 | max 3 |
Diminishing returns: after 30 points deducted in a category, further deductions are halved; after 50, quartered.
Weighted overall: security 40%, reliability 30%, performance 15%, ai-quality 15%. Floor at 0. Exit code 1 if any critical findings exist.
GitHub Action
Add to .github/workflows/prodlint.yml:
name: Prodlint
on: [pull_request]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: prodlint/prodlint@v1
with:
threshold: 50
Posts a score breakdown as a PR comment and fails the build if below threshold.
| Input | Default | Description |
|---|---|---|
path |
. |
Path to scan |
threshold |
0 |
Minimum score to pass (0-100) |
ignore |
Comma-separated glob patterns to ignore | |
comment |
true |
Post PR comment with results |
| Output | Description |
|---|---|
score |
Overall score (0-100) |
critical |
Number of critical findings |
SARIF + GitHub Code Scanning
Upload prodlint results to GitHub's Security tab:
- name: Run prodlint
run: npx prodlint --sarif > prodlint.sarif
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: prodlint.sarif
category: prodlint
Baseline for Existing Projects
Adopt prodlint gradually without drowning in pre-existing findings:
# Save current state as baseline
npx prodlint --baseline-save .prodlint-baseline.json
# CI only fails on NEW findings
npx prodlint --baseline .prodlint-baseline.json
MCP Server
Use prodlint inside Cursor, Claude Code, or any MCP-compatible editor:
Claude Code:
claude mcp add prodlint -- npx -y -p prodlint prodlint-mcp
Cursor / Windsurf:
{
"mcpServers": {
"prodlint": {
"command": "npx",
"args": ["-y", "-p", "prodlint", "prodlint-mcp"]
}
}
}
-p prodlint runs the MCP server straight from the prodlint package, so you always get
the current scanner.
Ask your AI: "Run prodlint on this project" and it calls the scan tool directly.
Site Score
Check any deployed website for AI agent-readiness โ 14 checks covering emerging standards like llms.txt, TDMRep, AgentCard, AI-Disclosure, HTTP Signatures (RFC 9421), and more.
npx prodlint --web example.com
npx prodlint --web example.com --json # JSON output
prodlint site score
example.com ยท 14 checks
Score: 42 C โโโโโโโโโโโโโโโโโโโโ
โ AI-Disclosure Header 0/10 No AI-Disclosure header found.
โ Content-Usage Directives 0/10 No Content-Usage directives found.
โ TDMRep 0/10 No TDMRep found.
โ A2A AgentCard 0/5 No agent-card.json found.
โ ai.txt 0/5 No ai.txt found at site root.
! llms.txt 2/5 llms.txt found but missing key sections.
โ robots.txt 10/10 robots.txt found with 15 rules.
โ Sitemap 10/10 Valid sitemap with 42 URLs.
โ Structured Data 10/10 Found JSON-LD structured data.
โ OpenGraph 10/10 Complete OpenGraph tags found.
โ Page Speed 5/5 Loaded in 0.8s.
โ AI Bot Directives 5/5 AI-specific bot rules found.
โ WebMCP Tools 0/5 No WebMCP tools detected.
7 passed ยท 5 failed ยท 1 warnings
Full results: https://prodlint.com/score?url=example.com
Or check your score interactively at prodlint.com/score.
For AI Tools
- LLM-friendly docs: prodlint.com/llms.txt โ concise project summary for LLMs
- Full reference: prodlint.com/llms-full.txt โ all 52 rules with details
- MCP setup guide: prodlint.com/mcp โ detailed editor setup for Claude Code, Cursor, Windsurf
prodlint is designed specifically for AI-generated code patterns. Every rule checks for production issues that AI coding tools consistently create โ not style nits.
Suppression
Suppress a single line:
// prodlint-disable-next-line secrets
const key = "sk_test_example_for_docs"
Suppress an entire file (place at top):
// prodlint-disable secrets
Programmatic API
import { scan } from 'prodlint'
const result = await scan({ path: './my-project' })
console.log(result.overallScore) // 0-100
console.log(result.findings) // Finding[]
Badge
[](https://prodlint.com)
License
MIT
Install
Add prodlint to your client. Pick the one you use.
claude mcp add prodlint-mcp -- npx -y prodlint-mcpcodex mcp add prodlint-mcp -- npx -y prodlint-mcpamp mcp add prodlint-mcp -- npx -y prodlint-mcp{
"mcpServers": {
"prodlint-mcp": {
"command": "npx",
"args": [
"-y",
"prodlint-mcp"
]
}
}
}Add to `claude_desktop_config.json`, then restart Claude Desktop.
{
"mcpServers": {
"prodlint-mcp": {
"command": "npx",
"args": [
"-y",
"prodlint-mcp"
]
}
}
}Add to `~/.cursor/mcp.json`, or `.cursor/mcp.json` for a single project.
code --add-mcp '{"name":"prodlint-mcp","command":"npx","args":["-y","prodlint-mcp"]}'Or add the block manually to `.vscode/mcp.json` under `servers`.
{
"mcpServers": {
"prodlint-mcp": {
"command": "npx",
"args": [
"-y",
"prodlint-mcp"
]
}
}
}Add to `~/.codeium/windsurf/mcp_config.json`.
{
"mcpServers": {
"prodlint-mcp": {
"command": "npx",
"args": [
"-y",
"prodlint-mcp"
]
}
}
}Add to `cline_mcp_settings.json` via the MCP Servers panel.
{
"mcpServers": {
"prodlint-mcp": {
"command": "npx",
"args": [
"-y",
"prodlint-mcp"
]
}
}
}Add to `~/.gemini/settings.json`.
{
"mcpServers": {
"prodlint-mcp": {
"type": "local",
"command": "npx",
"args": [
"-y",
"prodlint-mcp"
],
"tools": [
"*"
]
}
}
}Add to `~/.copilot/mcp-config.json`, or run `/mcp add` inside the CLI.
{
"context_servers": {
"prodlint-mcp": {
"command": {
"path": "npx",
"args": [
"-y",
"prodlint-mcp"
]
}
}
}
}Add to your Zed `settings.json`.
npx -y prodlint-mcpRun `goose configure`, choose **Add Extension โ Command-line Extension**, and paste this command.
Score
39 / 100
Incomplete
- Documentation25/25
- Maintenance19/25
- Trust16/20
- Capability0/15
- Install experience12/15
- Documents what it does and how to connect
- Has a resolvable package or endpoint
- Exposes at least one tool, prompt or resource
- README has substantive content
- Includes a code example
- Documents its configuration
- Mentions credentials or security posture
- Last commit 1 days ago
- Has a release history
- Repository is not archived
- Licensed MIT
- Namespace verified in the official MCP registry
- Claimed by its owner
- Published under an organisation
- 0 tool(s) documented
- Provides prompt templates
- Provides resources
- 12 documented install method(s)
- Published to a package registry
- Offers a hosted endpoint โ no local install
Version history
| Versions | Published |
|---|---|
| 0.10.0Latest | Aug 9, 2026 |
| 0.9.5 | Jun 29, 2026 |