Feature request: per-plugin hook disable (keep skills/commands, opt out of hooks)

Resolved 💬 4 comments Opened May 10, 2026 by dbyron-sf Closed May 12, 2026

Summary

When a user installs a plugin from a marketplace, they get all of its components — skills, slash commands, agents, and hooks — as a bundle. There's no documented way to opt out of just the hooks while keeping the rest of the plugin enabled. Today the only documented options are:

  1. Disable the entire plugin via /plugin disable <plugin>@<marketplace> (loses skills + commands too)
  2. Set disableAllHooks: true (turns off every hook from every plugin, plus any user-defined ones)
  3. Fork the plugin and remove hooks/ from the fork

A per-plugin or per-hook disable would let users keep the parts of a plugin they want and opt out of the parts they don't.

Concrete use case

A plugin ships:

  • A skill describing how to compose a git commit message — useful, want to keep.
  • A PreToolUse hook on Bash(git commit *) that gates commits on the skill having been invoked — useful in some workflows, annoying in others (e.g. when the user is also running another commit-related slash-command plugin and doesn't want the two interacting).

The user wants the skill loaded and discoverable via /<skill-name> slash invocations. They don't want the hook firing on every git commit. Today, the only way to get that is to fork the plugin and strip its hooks/ directory before installing — which means losing automatic updates and turning a marketplace consumer into a maintainer.

The same shape applies to:

  • A plugin that ships both a security review skill and a hook that blocks gh pr create until the skill has been read.
  • A plugin that ships both a database migration skill and a hook that runs lint checks on every git commit.
  • Any plugin where the hook is one of multiple components and a user wants the others without the hook.

What's been tried

  • /plugin disable — too coarse. Disables skills and commands too.
  • disableAllHooks: true — too coarse and too surprising. Disables every plugin's hooks, plus the user's own hooks, often as a side effect of trying to opt out of just one.
  • Editing files under ~/.claude/plugins/cache/<marketplace>/<plugin>/<version>/hooks/hooks.json — not durable. The cache is regenerated on /plugin marketplace update and /plugin install. Any edits get clobbered.
  • Forking the plugin — works, but turns every marketplace consumer into a maintainer.

Proposed shapes

Any of these would address it; they're listed in increasing scope.

  1. Per-plugin hook disable — settings.json field that disables all hooks from a specific plugin while keeping the plugin's skills and commands enabled:

``json
{
"pluginOverrides": {
"<plugin>@<marketplace>": {
"disableHooks": true
}
}
}
``

  1. Per-event-type hook disable — disable a plugin's PreToolUse hooks but leave its SessionStart hooks alone (for example):

``json
{
"pluginOverrides": {
"<plugin>@<marketplace>": {
"disabledHookEvents": ["PreToolUse"]
}
}
}
``

  1. Per-named-hook disable — most granular. Requires hooks to be named in the plugin's hooks.json, then referenced by name in user settings:

``json
{
"pluginOverrides": {
"<plugin>@<marketplace>": {
"disabledHooks": ["check-commit-craft"]
}
}
}
``

(1) covers most real use cases and is the simplest to implement. (3) is the cleanest end state but requires a hook-naming convention the schema doesn't currently enforce.

A /plugin slash-command equivalent (e.g. /plugin disable-hooks <plugin>@<marketplace>) would make this discoverable without users having to know the settings.json schema.

Persistence requirements

The disable setting needs to live in ~/.claude/settings.json (or its project/local siblings), not in the plugin cache, and must survive /plugin marketplace update and /plugin install. The same persistence model enabledPlugins already uses for the whole-plugin disable case is the obvious template.

Honest limitations

Hooks are part of a plugin's design — disabling them silently can change the plugin's intended behavior. The setting should be:

  • Opt-in (no default disabling)
  • Visible (e.g. /plugin info <plugin> should surface that some of its hooks are disabled in the current session)
  • Logged when a hook would have fired but didn't, so users debugging behavior can correlate

Adjacent existing requests

  • #48840--no-hooks flag for claude -p. Different scope (CLI flag, not per-plugin), same theme of "give users a way to disable hooks more granularly."
  • #10447 — CLI commands for MCP server enable/disable. Same theme of "granular control over installed plugin pieces."

View original on GitHub ↗

This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗