Blog · 2026-11-07

What a Claude Code plugin runs before you type: we read 2,688 public plugins

We read the hooks, MCP servers and monitors of 2,688 Claude Code plugins in 1,961 active public repos. 30% of repos ship a plugin that runs something when a session starts, and 65% of npx-started MCP servers name no version.

Summary

Before you install a Claude Code plugin, open three things in its folder: hooks/hooks.json, .mcp.json and bin/. Look for SessionStart hooks, and for MCP servers started with npx or uvx but no version number.

The reason is simple. A plugin can run code before you type anything. The docs say it directly: “A Claude Code plugin you install can execute arbitrary code on your machine with your user privileges.” Four parts of a plugin start on their own:

  • SessionStart hooks run shell commands when a session starts. Their plain-text output is added to Claude’s context, which Claude “can see and act on”.
  • MCP servers declared with a command are processes Claude Code starts on your machine for an enabled plugin.
  • Monitors are shell commands that run in the background for the whole session and send their output to Claude.
  • bin/ is added to the PATH of the shell Claude runs commands in.

Claude Code runs all of these outside the sandbox, and installing a plugin also enables it.

So how many public plugins do this? We read every plugin in 1,961 active public repos.

Our picks

What we now check before installing a plugin:

  1. Read hooks/hooks.json, starting with SessionStart and Setup. These run when a session starts, and their output becomes context for Claude. Read the scripts they call, not just the command line, since most of them run a file from the plugin folder.
  2. Read .mcp.json. A server with command is a process on your machine. If it runs npx some-package or uvx some-package with no version, the package manager resolves a version at start. A new release can then reach your machine without any change to the plugin you reviewed. Pinned means a version after the name: @1.4.2 for npx, as in npx -y some-package plus @1.4.2, or ==1.4.2 for uvx, as in some-package==1.4.2.
  3. List everything before installing. Clone the repo and run claude --plugin-dir <plugin folder> plugin details <plugin name>. It reads the plugin’s files without starting a session and prints its hooks with their events, MCP and LSP servers, skills and agents.
  4. Decide on updates. With auto-update on for a marketplace, the docs note, “the files you reviewed can change on disk”. Turn it off for marketplaces you don’t control, or prefer ones that pin each plugin to a commit, as Anthropic’s community marketplace does for nearly every entry.

If the plugin ships a mod, read our review of 891 public mods for what to check there. We don’t repeat it here.

How we tested

  1. Find plugins. GitHub code search finds 34,157 plugin manifests (filename:plugin.json path:.claude-plugin). Search returns at most 1,000 results per query, so we split the search into 40 file-size slices. We ran them in alternating order under a 30-minute cap and finished 23, which cover every size range. That gave 17,965 unique manifests, about 53% of the total, from 17,928 repos.
  2. Filter repos. At least 5 stars, pushed to since October 7, not a fork, not archived: 1,964 repos. We read 1,961.
  3. Read every plugin in those repos. We read each plugin’s manifest, hooks/hooks.json and the hooks key, .mcp.json and the mcpServers key, .lsp.json, monitors/monitors.json and bin/, plus the scripts their commands name. All files come from the same commit: 2,688 plugins, read as text. Nothing was installed or run.
  4. Weigh by repo. Most repos hold one plugin; the largest holds 117. The main number is the share of repos with at least one such plugin. The other two are plugins capped at 10 per repo, and all plugins. They come out close.

Results

What the plugin doesRepos (of 1,961)Plugins, max 10 per repoAll plugins
Runs something when a session starts (SessionStart or Setup hook, local MCP server, or monitor)30.4%27.4%24.5%
SessionStart or Setup shell hook16.0%14.3%12.8%
…whose script writes files6.0%5.1%4.6%
…whose script goes online1.5%1.2%1.1%
Any shell hook22.2%20.1%18.5%
UserPromptSubmit hook (sees each prompt, output goes to Claude)8.1%7.0%6.3%
PreToolUse hook11.8%10.5%9.5%
Declares MCP servers26.3%24.1%21.3%
Local MCP server (a process on your machine)18.4%16.4%14.6%
Remote MCP server (a URL)8.6%8.2%7.2%
MCP server started by npx or bunx5.9%5.5%4.9%
…with no version3.9%3.5%3.2%
MCP server started by uvx with no version1.4%1.2%1.0%
Any package-manager-started MCP server with no version5.3%4.7%4.2%
Passes an environment variable named like a secret to an MCP server2.4%2.1%1.9%
bin/ folder on Claude’s PATH9.5%8.0%7.1%
Ships a mod (see the mods review)5.3%4.9%4.3%
Monitors0.4%0.3%0.3%
Sets defaultEnabled: false0.1%0.0%0.0%

Quick guess: of the MCP servers these plugins start with npx or bunx, how many name a version? About one in three. Of 171 such servers, 112 (65%) name none: they use @latest, a bare package name, or a GitHub reference. 149 (87%) pass -y, which skips npm’s install prompt. Across all 945 MCP servers, the most common kinds are remote URLs (445), local scripts in the plugin (176) and npx (164).

A few examples, without names:

  • Session start. Most SessionStart hooks run a script from the plugin folder with node, bash or python3, with file names like session-start, resume-hint or context-inject. Of the 29 repos whose session-start script goes online, 26 check for updates against GitHub or npm, and several talk to their own service on localhost. Around ten mention telemetry or analytics; we did not check what they send.
  • Your API key. One rule-checking hook calls Anthropic’s API with your ANTHROPIC_API_KEY and sends a slice of the conversation to judge it. Its comments say so. It spends your quota and sends your conversation, which you may want to know before installing.
  • Credential paths. Hooks that name ~/.ssh or .env were mostly guards that list those paths in order to block them.

None of the plugins our rules flagged looked malicious when we read them.

What to ignore

The number of components. A plugin with twenty hooks can be a careful guard, and a plugin with one SessionStart script and an unpinned npx server is the one to read closely. Look at what starts by itself and what it fetches.

Limitations

  • A sample. About 53% of manifests, from active repos with 5 or more stars, as of November 6, 2026. This is what public plugin repos contain, not what people actually install.
  • Static only. We did not run hooks, so we don’t know what context they add or what an online script sends.
  • Unpinned is a risk, not a measurement of harm. Whether a new version reaches you depends on the package manager’s cache. Without a version, nothing in the plugin has to change for different code to run.
  • Mods are counted, not analyzed. See the mods review for those.

Reproduce it

The counts above, in all three weightings, are in plugin-startup-2026-11.json. Repo and plugin names are left out. To check a plugin yourself, run claude --plugin-dir <plugin folder> plugin details <plugin name> and read the files it lists.

For skills you choose to install yourself, the AgentCraft skills directory lists 5,101 Claude Code skills, and every community skill is reviewed before it’s listed.

All of our checks are on one page: the Claude Code safety checklist.

Sources

  1. Claude Code docs: Plugin security and trust · official
  2. Claude Code docs: Hooks (SessionStart, hook output) · official
  3. Claude Code docs: Add components to a plugin (monitors, MCP servers, bin/) · official
  4. AgentCraft: We read 891 public Claude Code mods before installing any · blog