wellworn

Claude Code plugin

What the Wellworn plugin installs, which commands make its PreToolUse hook fire, and how to turn the hook off.

The plugin is three small files: the MCP server entry, a skill that tells Claude when to ask Wellworn, and a hook that prints known traps before a package install runs. Everything in it is in the public repository under plugins/claude-code, and none of it needs an account.

Install

claude plugin marketplace add WellWorn-dev/wellworn
claude plugin install wellworn@wellworn

The marketplace manifest sits at .claude-plugin/marketplace.json in the repository root and points at ./plugins/claude-code. Both names in wellworn@wellworn are real: the first is the plugin, the second is the marketplace. The same two steps work as /plugin marketplace add and /plugin install inside a session.

Verified 2026-09-08 against code.claude.com

What the plugin contains

PathWhat it does
.mcp.jsonRegisters https://mcp.wellworn.dev/mcp as an HTTP MCP server named wellworn
skills/wellworn/SKILL.mdTells Claude which tool to call and how to read a verdict
hooks/hooks.jsonRegisters one PreToolUse hook on Bash and one on Edit|Write|MultiEdit
scripts/check-traps.shThe hook itself: reads the pending tool call, asks the traps endpoint, prints what comes back

The plugin ships no key and no configuration. To attach a key, add the server yourself with an Authorization header as described in Claude Code; the plugin's .mcp.json entry stays anonymous.

The hook

hooks/hooks.json registers the same script twice, once for the Bash matcher and once for Edit|Write|MultiEdit, each with an 8 second timeout. The script reads the pending tool call as JSON on stdin and decides in its first few lines whether this call is interesting.

Which commands trigger it

On Bash, the script pulls the command string out of the payload and keeps going only if it contains one of these substrings:

npm install    npm i     pnpm add    yarn add    bun add
pip install    uv add    composer require        cargo add

Anything else exits immediately, so npm run build and npm ci never reach the network. From a matching command it takes the package names, drops flags and the package manager's own words, strips a pinned version off the end, and keeps at most eight names.

Which files trigger it

On an edit, the script reads file_path and continues only for package.json, pyproject.toml, requirements.txt, composer.json, Cargo.toml, go.mod, or Gemfile. It then scans the new content for "name": "1.2.3" pairs. Claude Code sends that content as an escaped JSON string, and the script's extraction stops at the first escaped quote, so in practice this path prints nothing and the install command is what fires the hook.

What it sends and prints

For each name the script requests the plain-text traps endpoint with a 4 second timeout:

GET https://mcp.wellworn.dev/api/traps?library=better-auth

The library name is the only thing that leaves the machine. No file contents, no command line, no version: the version is stripped before the request, so the answer covers every range recorded for that library. A 204 (nothing recorded) or a failed request is skipped silently. Whatever text comes back is wrapped in the additionalContext field Claude Code reads for PreToolUse, which puts it in front of the model without touching the permission decision:

hook output
{"hookSpecificOutput":{"hookEventName":"PreToolUse","additionalContext":"TRAPS Better Auth (1)\n  [187fc511] blocker >=1.7.0 <1.7.2: organization invitations fail when teams are enabled\npass id for the full fix\n"}}

The script always exits 0, so it can slow a tool call down but never block one. It needs curl and python3 on the PATH and exits quietly without them. Each request counts against the same limit as an MCP tool call: 60 a day per IP anonymously. See the traps API for the response format and keys for raising the cap.

Verified 2026-09-08 against code.claude.com

When the skill calls Wellworn

The hook covers installs. The skill covers the decision before the install, and it names the tool per situation:

plugins/claude-code/skills/wellworn/SKILL.md
## When to call it

- Before `npm install`, `pip install`, `composer require`, `cargo add`, or editing a dependency manifest: call `recommend` with the task in one sentence and any constraints (solo, free tier, serverless, RTL, offline).
- When two options are on the table: call `compare` with the names.
- When a SaaS is being considered: call `alternatives` for open-source or self-hosted options.
- Before a UI screen: call `design` with the screen and constraints.
- After an upgrade breaks something: call `traps` with the library and the version from the lockfile; pass an id for the full fix.

The rest of the file is the shape of a verdict and the rule for reading one: follow PICK unless the ALT condition applies to this project, and read every blocker trap before writing code. The tools reference documents the same five tools with their arguments.

Turning it off

To keep the server and the skill but stop the hook, disable the plugin and add the server on its own:

claude plugin disable wellworn@wellworn
claude mcp add --transport http wellworn https://mcp.wellworn.dev/mcp

claude plugin uninstall wellworn@wellworn removes it completely. To silence every hook in a session without changing what is installed, start Claude Code with --settings '{"disableAllHooks": true}'.

Verified 2026-09-08 against code.claude.com