npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ctrlsec

v1.4.0

Published

CTRL_ — security audit MCP server for AI-generated Next.js, Vite and Express apps. Finds exposed keys, unsafe queries and open row-level security, then walks your coding agent through fixing them. Extra depth on Supabase.

Readme

CTRL_

Finds the security mistakes AI coding agents leave behind — before you ship.

npm node license

An MCP server for JavaScript and TypeScript projects — Next.js, Vite and Express. Your coding agent runs the audit, then CTRL_ walks it through fixing each finding, one at a time, re-checking after every edit. 31 of the 35 checks need no backend at all. Four are Supabase-specific — row-level security, policies that let every row through, public storage buckets, and a service-role key reaching the browser — and a Supabase project can opt into a live check against the database itself.

Quick start

Write your editor's MCP config automatically — detects Cursor, VS Code, Claude Desktop and Windsurf:

npx ctrlsec init

Or add it by hand:

{
  "mcpServers": {
    "ctrlsec": {
      "command": "npx",
      "args": ["-y", "[email protected]"]
    }
  }
}

Restart your editor, then say "run a CTRL_ audit." The version is pinned deliberately: a bad release should not break every user at once.

The same binary is a CLI, for demos and CI:

npx ctrlsec audit            # current directory
npx ctrlsec audit ./apps/web # or a subdirectory

It exits non-zero when anything is severe enough to block a launch, so it can gate a pipeline.

What it catches

35 checks, grouped by how they are fixed:

| Category | Checks | Examples | | --- | --- | --- | | Secrets & Config | 10 | live API key in the repo, committed .env, private key file, secret in a CI config | | Injection | 6 | SQL built by interpolation or concatenation, eval, shell commands, unescaped HTML | | Auth & Access Control | 5 | unverified JWTs, admin gates enforced only in the browser, tokens in localStorage | | Framework & Client | 5 | whole process.env sent to the client, server-only env vars in browser code | | Database & BaaS | 3 | row-level security off, a policy that lets every row through, a public storage bucket | | Transport & Headers | 3 | wildcard CORS with credentials, unverified webhooks, plain http:// | | AI & LLM | 2 | provider key exposed to the browser, a completion call with no token cap | | Dependencies | 1 | install scripts that run unreviewed code |

Every response says how many checks ran and how many were skipped, so "nothing found" can never be confused with "nothing was looked at".

The live Supabase check

Most scanners read your migration files and infer what should be true. CTRL_ can go further: with your permission it connects to your own Supabase project with the public anon key — the same key any visitor's browser holds — and asks the database directly whether a table answers. A table that returns a row to an anonymous request is not a guess about a missing policy. It is proof.

It is opt-in and stays inside hard limits, all confined to one auditable module:

  • Granted only by running npx ctrlsec audit --probe yourself, and remembered per Supabase project in ctrl.config.json. The MCP tools can read that consent, never grant it.
  • The public anon key only — never service_role, even when it is sitting in .env.
  • Read-only. select ... limit 1 and bucket listing. No writes, no schema changes.
  • Row contents are discarded the moment they arrive. Only "did anything come back" is kept.
  • Bounded: 25 tables per scan, a 4-second timeout, and any failure falls back to reading migrations rather than reporting a pass.

Without consent, CTRL_ reads supabase/migrations/*.sql instead. Anything it can resolve neither way is reported as could not be verified and named explicitly — never quietly passed.

The fix loop

ctrl_audit finds and groups the issues. ctrl_fix works through them:

| Action | What it does | | --- | --- | | next | the most severe unresolved issue, with a pre-authored fix | | verify | re-scans, confirms the issue is gone, and hands over the next one | | explain | the same finding in plain language, for a human | | ignore | suppresses it in .ctrlignore — a scope and a written reason are required |

Two things keep the loop honest. Regression detection: if the edit introduced a new finding, verification aborts and says so instead of marking the original resolved. And a two-attempt cap: after two failed attempts an issue is marked Requires Human Review and the loop moves on, rather than letting an agent grind at it.

Verification confirms the security rule is resolved. It cannot confirm your application still works — run your own tests for that.

Your code never leaves your machine

Analysis is entirely local. No source, no file paths, no findings and no secrets are uploaded anywhere — the rules ship inside this package and run in the same process your editor spawns. Nothing is downloaded at scan time either: rules delivered over a network would make a security scanner an attractive supply-chain target.

The one network request CTRL_ can make is the Supabase probe described above — to your own project, only after you have granted consent on the command line.

CTRL_ reports which checks passed and which did not. It will never tell you an application is secure; no tool can know that.

Supported stacks

| Stack | Detected as | Notes | | --- | --- | --- | | Next.js App Router | next-app | server routes; client boundary from "use client" | | Next.js Pages Router | next-pages | detected from a pages/ directory | | Vite + React | vite | the shape Lovable and Bolt export — no server, VITE_ env prefix | | Express | express | server routes, no client bundle |

Supabase, Firebase and Clerk are detected from your dependencies. Four checks are gated on Supabase — the three Database & BaaS rules above, plus the service-role key check, which is about a Supabase key specifically. On a Firebase or Clerk project those four are reported as skipped rather than counted as passed. The same applies to framework-specific checks — on a Vite project the four Next.js config checks are reported as skipped, by name.

Example output

What your agent receives, and relays to you:

**CTRL_ audit complete**

**3 issues found** · 3 fix now

Checked 31 of 35 rules. 4 skipped — no Next.js detected.

**Fix now**

- **S03** — Anyone who can clone this repo has every secret in your `.env` file · `.env`
- **S01** — Anyone who can read this repo can use your live API key · `src/lib/billing.ts`
- **S02** — Your admin database key is shipped to every visitor's browser · `src/lib/supabase.ts`

**1 table could not be verified** — profiles. Run `npx ctrlsec audit --probe` to check it live.

Findings lead with what an attacker can do, not with the name of the mechanism.

Security

Found a vulnerability in CTRL_ itself? Email [email protected]. Please do not report it publicly.

More at heyctrl.com.