# Cursor community-plugins: the directory site behind cursor.directory

> This repository is the Next.js application that powers cursor.directory, a submission and browsing site for Cursor plugins. It is infrastructure, not a plugin collection you install, and it expects Bun and a Supabase project before it will start.

**cursor/community-plugins** — Plugins from the Cursor community

- Repository: https://github.com/cursor/community-plugins
- Website: https://cursor.directory
- Stars: 4,000 · Forks: 672
- Language: TypeScript
- License: not declared
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/cursor-community-plugins

## What cursor/community-plugins actually is

The name invites a misreading. This is not a curated bundle of Cursor plugins that you clone and point your editor at. The README opens by calling it "the directory of plugins from the Cursor community" and links to cursor.directory, and the repository layout confirms the shape: an apps/cursor Next.js application, a supabase/migrations directory, and a root package.json that declares a Bun workspace over packages/* and apps/*. The package name in that manifest is "directories", not anything plugin related.

So the audience is narrow. You are the right reader if you want to operate a plugin directory: accept submissions, detect their components, scan them for malicious content and publish them. You are the wrong reader if you want to add a rule file or an MCP server to your own Cursor setup. For that, the README points at the website, not the repository. The README also states plainly that all data lives in the database and there is no local data in the repo, which means a fresh clone renders an empty directory until you connect Supabase and apply migrations.

## The submission pipeline and the Open Plugins component detection

Content enters through the website rather than through pull requests. The README is explicit: "All content is submitted through the website, no pull requests needed for data." A submitter goes to cursor.directory/plugins/new, signs in with GitHub or Google, pastes a GitHub repo URL, and the system auto-detects components that follow the Open Plugins standard. The README lists exactly which paths are recognised: rules/*.mdc for rules, .mcp.json for MCP servers, skills/*/SKILL.md for skills, agents/*.md for agents, hooks/hooks.json for hooks, and .lsp.json for LSP servers.

That fixed path table is the contract. A plugin that keeps its rules somewhere else, or names its agent files differently, will be submitted with fewer detected components than its author expects, and the README does not describe an override or a manual component editor. The design also means the directory has no editorial queue for data changes: correctness of the listing depends on the repository layout of the submitted project at the moment of detection.

## How the asynchronous security scan works

The most interesting part of the repository is the scan pipeline, and the README documents it in enough detail to reason about failure. Submitted plugins are reviewed by a Cursor SDK agent running the model composer-2 in local mode, against a fresh clone of the plugin repository plus its inline component content. The verdict is one of safe, suspicious or malicious, written to the plugins.scan_status column and surfaced in an admin queue.

The scan deliberately runs outside the request lifecycle. Server actions and a recover-stuck-scans cron call enqueuePluginScan(pluginId), which pushes a message onto the plugin_scans pgmq queue. User-facing actions additionally call kickDrainAfterResponse() so the drain route is invoked through next/server after() once the response is flushed; the README says scans typically start within a few hundred milliseconds. The drain endpoint at /api/queue/plugin-scans/drain reads one message with vt=900s and n=1, runs runPluginScan(pluginId), then archives the message on success, leaves it in place for visibility-timeout expiry on a retryable error, or buries it after MAX_ATTEMPTS=5 deliveries. A Vercel cron hits the same route every minute as a safety net.

The queue semantics are the real design decision here. A visibility timeout of 900 seconds means a scan that hangs will not be retried for fifteen minutes, and a scan that fails repeatedly is buried rather than alerted on. The README does not describe how buried messages are surfaced to an operator, so a plugin can sit without a verdict and the only documented place its state appears is the admin queue.

## Installing it locally with Bun and Supabase

The README gives a five-step setup. You need Bun and a Supabase project before anything else, and the repository ships an .env.example under apps/cursor that you copy into place. Start by cloning and installing:

```bash
git clone https://github.com/cursor/community-plugins.git
cd community-plugins
bun install
```

Bun installs the workspace dependencies declared in the root package.json, which covers packages/* and apps/*. Next, create the environment file:

```bash
cp apps/cursor/.env.example apps/cursor/.env
```

Four variables are documented in the README's table. NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY are required, as is SUPABASE_SECRET_KEY; NEXT_PUBLIC_APP_URL is optional and defaults to http://localhost:3000. The README notes that the publishable key uses the sb_publishable_ prefix and replaces the legacy anon key, and that the secret key uses sb_secret_ and replaces the legacy service role key.

Then apply the migrations in supabase/migrations/ to your Supabase project, and start the dev server:

```bash
bun dev
```

The README says to open http://localhost:3000. Because all data lives in the database, the first useful thing you will see is an empty directory backed by your Supabase instance, not sample plugins. Note that the scan pipeline additionally relies on CURSOR_API_KEY and CRON_SECRET from the env file, and the drain route sets maxDuration = 800, which the README ties to the Vercel Pro+ Fluid Compute ceiling.

## Limits, gaps and the wrong use case

The repository metadata does not state a licence. For a project you intend to self-host, that is the first thing to resolve, and the README does not address it either. Treat the absence as a real constraint rather than an oversight you can assume away.

The README also documents no rollback or re-scan path. A plugin that was scanned as safe and later changes its repository content has no described mechanism for re-evaluation, and the buried-after-five-attempts behaviour has no documented operator notification. There is no local seed data, so you cannot evaluate the interface meaningfully without standing up Supabase and running migrations first. Search is client-side Fuse.js over data fetched from the database, which the README lists in the tech stack but does not describe in terms of index size or behaviour at scale.

Finally, this is the wrong tool if your goal is to consume plugins. Nothing in the README describes a CLI, a package to install into Cursor, or an export format. The only documented consumption path is the hosted site.

## How it differs from Backstage and Obsidian plugin registries

People searching around this project often arrive from other plugin ecosystems, and the comparison is worth making precisely. Backstage's community-plugins repository is a monorepo of source packages that you install into a Backstage app through the package manager; the artifact is code you import. Obsidian's community plugins are distributed through an in-app browser that installs a plugin folder into a vault. Both ship the plugin to the user.

This repository ships the registry instead. It is a Next.js application with Supabase as the store and pgmq as the work queue, and its output is a website plus a scan verdict. The unit of contribution is a GitHub URL submitted through a form, not a package published to a registry or a folder dropped into an application. If you want to run a directory with automated security review, this is the closer fit. If you want to distribute code that developers import, it is not.

## Maintenance, upgrades and licence exposure

The last push to the default branch was on 2026-09-11, which is recent enough that the codebase is moving. There are no retrieved releases, so there is no tagged version to pin against and no changelog to read before upgrading. In practice that means tracking main and re-reading the migration files under supabase/migrations/ before applying them, since the README gives no migration versioning or rollback procedure.

The upgrade surface is larger than a typical web app because the runtime is spread across four systems: Bun for the workspace, Next.js with Turbopack for the app, Supabase for PostgreSQL and Queues, and Vercel cron for the drain safety net. The drain route's maxDuration = 800 ties your hosting tier to whether scans can complete, and the scan itself depends on an external Cursor SDK agent and a CURSOR_API_KEY, so a change in that service is an upgrade event you do not control. The licence question remains open and is the item to settle before any deployment that is not purely local.

## Conclusion

Adopt this repository if you want to run a plugin directory of your own on the Open Plugins standard, and you are comfortable operating Next.js, Bun and a Supabase project with pgmq queues and a Vercel cron. Do not adopt it if you were looking for a plugin to install into Cursor: this repo contains no plugin content, all data lives in the database, and the README offers no path to a standalone plugin bundle. Before committing, verify the licence, since the repository metadata does not state one, confirm that your Supabase project supports Queues and pgmq, and check that your hosting tier allows a drain route with maxDuration = 800, because the scan pipeline depends on it.

## FAQ

### What is cursor/community-plugins?

It is the Next.js application that powers cursor.directory, the directory of plugins from the Cursor community. The README describes it as a submission and browsing site, with all data stored in a Supabase database rather than in the repository.

### Where do I find plugins for Cursor?

The README points to cursor.directory, and submissions are made at cursor.directory/plugins/new by pasting a GitHub repository URL. The repository itself contains no plugin content, only the application that serves the directory.

### How do I install cursor/community-plugins locally?

Clone the repository, run bun install, copy apps/cursor/.env.example to apps/cursor/.env and fill in the Supabase variables, apply the migrations in supabase/migrations/, then run bun dev and open http://localhost:3000. Bun and a Supabase project are listed as prerequisites.

### What components does cursor/community-plugins auto-detect in a submitted plugin?

The README lists rules/*.mdc for rules, .mcp.json for MCP servers, skills/*/SKILL.md for skills, agents/*.md for agents, hooks/hooks.json for hooks, and .lsp.json for LSP servers, following the Open Plugins standard.

### Does cursor/community-plugins scan submitted plugins for security?

Yes. The README states that a Cursor SDK agent running composer-2 in local mode reviews a fresh clone of the plugin repository plus its inline component content, and writes a verdict of safe, suspicious or malicious to plugins.scan_status. The scan runs asynchronously through a pgmq queue drained by a route that a Vercel cron also calls every minute.

## Sources

- [cursor/community-plugins on GitHub](https://github.com/cursor/community-plugins)
- [Issues](https://github.com/cursor/community-plugins/issues)
- [Project website](https://cursor.directory)
- [README](https://github.com/cursor/community-plugins/blob/main/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/cursor-community-plugins
