Scan your source code, your live site, or both. Finds bugs before your users do.
cd ~/projects/my-app # go to your project
npx sniff-qa # that's itSniff auto-detects everything: your framework, your dev server port, and your running app. If npm run dev is running, sniff finds it and runs browser checks too. No flags needed.
You can also be explicit:
npx sniff-qa --url http://localhost:3000 # specific local URL
npx sniff-qa --url https://myapp.com # production URLNo API keys. No Playwright install. No config files. Everything works out of the box. Browser checks auto-install Chromium on first run.
Sniff ships as an MCP server. Add it to your editor, then ask your AI to scan.
Claude Code
claude mcp add sniff-qa npx sniff-qa --mcpCursor
Add to ~/.cursor/mcp.json:
{ "mcpServers": { "sniff-qa": { "type": "stdio", "command": "npx", "args": ["sniff-qa", "--mcp"] } } }VS Code + Copilot
Add to .vscode/mcp.json:
{ "servers": { "sniff-qa": { "type": "stdio", "command": "npx", "args": ["-y", "sniff-qa", "--mcp"] } } }Codex CLI
codex mcp add sniff-qa -- npx -y sniff-qa --mcpWindsurf
Add to ~/.codeium/windsurf/mcp_config.json:
{ "mcpServers": { "sniff-qa": { "command": "npx", "args": ["sniff-qa", "--mcp"] } } }Gemini CLI
Add to ~/.gemini/mcp_config.json:
{ "mcpServers": { "sniff-qa": { "command": "npx", "args": ["sniff-qa", "--mcp"] } } }Continue.dev
Add to .continue/mcpServers/sniff-qa.yaml:
mcpServers:
sniff-qa: { command: npx, args: [sniff-qa, --mcp], type: stdio }OpenClaw
clawhub install sniff-qaThen ask: "Scan this project for issues" or "Check accessibility on localhost:3000"
MCP tools: sniff_scan (source) · sniff_run (browser) · sniff_report (results)
npm install -D sniff-qa{
"scripts": {
"qa": "sniff",
"qa:full": "sniff --url http://localhost:3000"
}
}Requires Node.js 22+. Playwright installs automatically on first browser scan.
npx sniff-qa # scan source + auto-detect dev server
npx sniff-qa --url https://myapp.com # scan source + specific URL
npx sniff-qa ./path/to/project # scan a specific directory
npx sniff-qa --ci # CI mode (JUnit output, no AI explorer)Sniff auto-detects your dev server by reading package.json scripts and probing common ports (3000, 5173, 8080, 4200). If it finds a running server, browser checks run automatically.
Source checks run on every scan. Browser checks activate when you pass --url.
| Command | What it does |
|---|---|
/sniff |
Scan the project. Auto-detects dev server, runs source + browser checks |
/sniff-fix |
Scan and auto-fix safe issues (debugger, console.log, etc.) |
/sniff-report |
Show results from the last scan |
sniff Scan source + auto-detect dev server
sniff --url <url> Scan source + test specific URL
sniff --url <url> --ci Full audit for CI pipelines
sniff <path> Scan a specific directory
sniff fix Auto-fix safe issues (debugger, console.log)
sniff fix --check Dry run: show what would be fixed
sniff init Create sniff.config.ts
sniff ci Generate GitHub Actions workflow
sniff report Show last scan results
sniff update-baselines Accept current visual baselines
sniff doctor Check your environment (Node, Playwright, config, dev server)
sniff --help Show all commands and flags
sniff --version Show version
All flags
| Flag | What it does |
|---|---|
--url <url> |
Enable browser checks (accessibility, visual, performance, AI) |
--ci |
CI mode: skip AI explorer, add JUnit output, track flaky tests |
--no-explore |
Browser checks without AI explorer |
--no-browser |
Source only even if --url is set |
--max-steps <n> |
Limit AI explorer steps (default: 50) |
--no-headless |
Show the browser window |
--format html,json,junit |
Choose report formats |
--fail-on critical,high |
Severities that cause non-zero exit |
--track-flakes |
Track test flakiness across runs |
--json |
JSON output for scripts |
Sniff auto-detects your framework. No config needed.
| React JSX / TSX |
Next.js App + Pages |
Vue SFC |
Svelte Components |
Angular Templates |
Express Routes |
Vanilla HTML / CSS |
API discovery also supports Fastify, Hono, tRPC, and GraphQL.
Sniff works with zero config. Only create a config file if you want to customize.
npx sniff-qa initsniff.config.ts reference
import { defineConfig } from 'sniff-qa';
export default defineConfig({
// Save your URL so you can just run `sniff`
browser: { baseUrl: 'http://localhost:3000' },
// Viewports to test
viewports: [
{ name: 'mobile', width: 375, height: 667 },
{ name: 'desktop', width: 1280, height: 720 },
],
// Performance budgets (ms)
performance: { budgets: { lcp: 2500, fcp: 1800, tti: 3800 } },
// Visual regression threshold (0-1)
visual: { threshold: 0.1 },
// AI explorer
exploration: { maxSteps: 50 },
// Dead link checker
deadLinks: {
checkExternal: true,
timeout: 5000,
retries: 2,
ignorePatterns: [],
maxConcurrent: 10,
},
// API endpoint discovery
apiEndpoints: {
checkErrorHandling: true,
checkValidation: true,
checkAuth: true,
checkSecrets: true,
frameworks: [], // empty = auto-detect all
},
// Turn off specific rules
rules: {
'debug-console-log': 'off',
},
});All rule IDs
| Rule | Severity | What it checks |
|---|---|---|
debug-console-log |
medium | console.log/debug/info |
debug-debugger |
high | debugger statements |
placeholder-lorem |
high | Lorem ipsum text |
placeholder-todo |
medium | TODO comments |
placeholder-fixme |
high | FIXME comments |
placeholder-tbd |
medium | TBD markers |
hardcoded-localhost |
medium | localhost URLs |
hardcoded-127 |
medium | 127.0.0.1 URLs |
broken-import |
medium | Unresolved imports |
dead-link-internal |
high | Broken file links |
dead-link-external |
medium | 404 external URLs |
dead-link-anchor |
medium | Missing anchors |
api-no-error-handling |
medium | Routes without try/catch |
api-no-validation |
medium | POST/PUT without validation |
api-no-auth |
low | Routes without auth |
api-hardcoded-secret |
critical | Hardcoded API keys |
Set any to 'off' to disable.
npx sniff-qa ciGenerates .github/workflows/sniff.yml with Playwright caching, JUnit output, and report artifacts.
Flakiness quarantine: Tests that fail 3 of 5 runs get quarantined. They still run, still report, but won't block your pipeline.
Architecture
No telemetry. No signup. No data collection. No API keys. Your code stays on your machine.
Note
All 8 checks work without any API key. The AI explorer uses Claude Code as the AI provider when run through MCP, so no separate Anthropic key is needed. Dead link checking validates external URLs but never sends your code.
Add a source rule: each rule is a regex + severity in src/scanners/source/rules/. See CONTRIBUTING.md.
Built on Playwright · axe-core · Lighthouse · pixelmatch · Zod · MCP SDK · Anthropic SDK
Built by Adam Boudjemaa · Apache 2.0