[FEATURE] Expose the plugin version to plugin skills as `${CLAUDE_PLUGIN_VERSION}`

Status Open
Reported on v2.1.281
Maintainer reply None cached
Activity 0 comments · opened Sep 26, 2026

Preflight Checklist

  • [x] I have searched existing requests and this feature hasn't been requested yet (well, it was: #78311, but the bot closed it for inactivity and nobody ever answered, see below)
  • [x] This is a single feature request (not multiple features)

Problem Statement

I maintain a plugin and I can't find any way for its skill to know which version of the plugin it's running from.

Claude Code obviously has this information. The plugin cache directory is named after the version (~/.claude/plugins/cache/<marketplace>/<plugin>/<version>/), it's stored in installed_plugins.json, claude plugin list prints it, and the claude_code.plugin_loaded OTel event has a plugin.version attribute ("version from the plugin manifest", per the monitoring docs). But what a skill actually gets is three directories: ${CLAUDE_PLUGIN_ROOT}, ${CLAUDE_PLUGIN_DATA} and ${CLAUDE_SKILL_DIR} (skills docs). I also grepped the 2.1.281 binary to be sure: the only CLAUDE_PLUGIN_* strings in there are ROOT, DATA and the OPTION_ prefix.

Why I need it:

  • My skill writes a Renovate config, and the first line of that file says which plugin and which version wrote it. Whoever opens the file later can tell if a newer release would have written something different, and bug reports come with the version already in them.
  • The skill shows a welcome screen and I want the version in the title, same as any CLI does.
  • I want to be able to tell from a transcript or an eval which version ran. #94359 is asking for the same thing on the skill_activated OTel event.

#78311 already asked for this (CLAUDE_PLUGIN_VERSION, _REF, _SHA env vars, plus version fields in plugin list --json). It was auto-closed on 2026-09-04 as inactive, with no answer from anyone. plugin list --json does have a version field now on 2.1.281, so the only part still missing, and the one that bites a skill author, is the substitution. That's all I'm asking for here.

Proposed Solution

A ${CLAUDE_PLUGIN_VERSION} substitution, right next to ${CLAUDE_PLUGIN_ROOT} and ${CLAUDE_PLUGIN_DATA}: replaced in the skill markdown and in allowed-tools Bash rules, and exported to hook, MCP and LSP subprocesses. The value would be whatever version management resolved, i.e. the same string used for the cache directory and printed by claude plugin list, unknown included.

If the resolved version isn't the one from plugin.json (a commit SHA when the version isn't declared, a content hash or <version>-<hash> for command sources), just pass it through as is. That's what plugin list and the cache directory already show, and plugin authors know which kind of version their plugin has.

Alternative Solutions

What I did instead: a small script under ${CLAUDE_SKILL_DIR}, run as ! dynamic context when the skill loads, that walks up from its own directory until it finds .claude-plugin/plugin.json and pulls version out of it with sed. Here it is: https://github.com/gwenneg/mintmaker-automerge/blob/cb36c705279cda4d4fcc2b7cfb46a27d3de421a0/skills/setup/scripts/version.sh

This works because ${CLAUDE_PLUGIN_ROOT} points at the versioned copy in the cache, so the plugin.json the script finds is always the one of the version that's running. It's not great though:

  • It has to be POSIX sh + sed so it runs everywhere a plugin can be installed, and it needs its own allowed-tools entry, otherwise outside auto mode the whole skill invocation aborts when the permission check doesn't return allow.
  • It only reads the version field of the manifest. A plugin that gets its version from the marketplace entry or from the git SHA gets unknown, even though Claude Code resolved a version for it.
  • Every plugin that wants this needs its own copy of the script, and every skill that runs it spawns a process at load time to get a value Claude Code already has in memory.

Putting the version in ${CLAUDE_PLUGIN_DATA} doesn't help either, that directory survives updates on purpose, so it's exactly where a stale version would end up.

Priority

Medium - Would be very helpful

Feature Category

Developer tools/SDK

Use Case Example

  1. Someone runs /mintmaker-automerge:setup in their repo.
  2. The welcome title says MintMaker Automerge Setup v0.9.0 and the generated config starts with // Set up with the MintMaker Automerge plugin v0.9.0: <repo url>.
  3. Six months later someone opens that config, sees the version and checks the plugin changelog for what changed since.
  4. Today step 2 needs the version.sh script above. With ${CLAUDE_PLUGIN_VERSION} the SKILL.md would just contain MintMaker Automerge Setup v${CLAUDE_PLUGIN_VERSION}.

View original on GitHub ↗