How Claude Plugins Enforce Shell-Safe Plugin Names: Validation Rules Explained

Claude plugins use a strict regex-based validation system that permits only lowercase alphanumerics and hyphens, preventing any shell metacharacters from entering the name field.

Plugin names in the anthropics/claude-plugins-community repository must remain safe for command-line usage and filesystem operations. This article explains the two-layer enforcement mechanism that keeps plugin names consistent and free of dangerous characters.

The Naming Constraint: Character Set and Pattern

Every plugin declares its identity through a "name" field in its manifest file. The repository enforces a rigid pattern that eliminates ambiguity in shell contexts.

The permitted pattern is defined by this regular expression:

^[a-z0-9][a-z0-9-]*$

This regex imposes three rules:

  • Start character: Must be a lowercase letter or digit
  • Body characters: Only lowercase letters, digits, and hyphens allowed
  • Forbidden characters: No spaces, no punctuation, no quotes, no brackets, no other shell metacharacters

The quickdesign plugin demonstrates a valid name in its manifest at quickdesign/.claude-plugin/plugin.json:

{
  "name": "quickdesign",
  "display_name": "QuickDesign",
  "description": "Visual UI for Claude Code plugins."
}

Layer 1: Manifest Declaration

Plugin authors define the name in the plugin manifest located at .claude-plugin/plugin.json within each plugin directory. This file serves as the canonical source of truth for the plugin's identifier.

The manifest separates concerns cleanly:

  • name: The machine-readable identifier (strictly validated)
  • display_name: The human-readable label (no restrictions)

This separation allows user-friendly presentation while maintaining shell-safe plugin names for technical operations.

Layer 2: CI Validation Script

The repository's Validate Plugins workflow runs automatically on every contribution. The critical validation logic lives in .github/actions/validate-plugins/scripts/20-validate-cli-marketplace.sh.

The script extracts and validates each plugin name:


# In 20-validate-cli-marketplace.sh

PLUGIN_NAME=$(jq -r .name "$PLUGIN_DIR/.claude-plugin/plugin.json")

if [[ ! "$PLUGIN_NAME" =~ ^[a-z0-9][a-z0-9-]*$ ]]; then
    echo "❌ Invalid plugin name: $PLUGIN_NAME"
    exit 1
fi

The workflow file at .github/workflows/validate-plugins.yml orchestrates this check. Any submission with an invalid name triggers an immediate CI failure, blocking the merge.

Why Shell Metacharacters Are Excluded

The plugin name consistency rules exist to prevent common shell injection and parsing vulnerabilities. Prohibited characters include:

Character Category Examples Risk
Whitespace space, tab Word splitting in shell commands
Quotes ", ' String termination attacks
Brackets [, ], {, } Glob expansion and command grouping
Redirection >, <, ` `
Variable expansion $, ` Command substitution attacks
Wildcards *, ? Unintended file matching
Other punctuation ;, &, ! Command sequencing and history expansion

The hyphen exception is safe because it holds no special meaning when positioned between alphanumeric characters.

Validation in Practice

A plugin author attempting to use an invalid name would encounter this CI output:

❌ Invalid plugin name: my_plugin

# Fails because underscore is not in [a-z0-9-]

❌ Invalid plugin name: 2cool4u!

# Fails because '!' is prohibited

❌ Invalid plugin name: MyPlugin

# Fails because uppercase 'M' is prohibited

The validation is case-sensitive and position-sensitive. A name starting with a hyphen would also fail, as the regex requires an alphanumeric first character.

Summary

  • Plugin names in Claude's community repository follow a strict ^[a-z0-9][a-z0-9-]*$ pattern
  • The plugin manifest at .claude-plugin/plugin.json declares the canonical name
  • CI validation in 20-validate-cli-marketplace.sh enforces the regex before any merge
  • This dual-layer system guarantees shell-safe plugin names across the entire ecosystem

Frequently Asked Questions

What happens if my plugin name contains an uppercase letter?

The CI validation rejects it. The regex ^[a-z0-9][a-z0-9-]*$ explicitly permits only lowercase letters. Convert your name to lowercase—for example, use "myplugin" instead of "MyPlugin".

Are underscores allowed in Claude plugin names?

No. The character set is strictly limited to lowercase letters, digits, and hyphens. Use hyphens as word separators: "my-plugin" rather than "my_plugin".

Where can I see the validation script in action?

Examine the workflow file at .github/workflows/validate-plugins.yml and the validation logic at .github/actions/validate-plugins/scripts/20-validate-cli-marketplace.sh. These run automatically on every pull request to the anthropics/claude-plugins-community repository.

Why restrict names when the display_name can be anything?

The name field appears in filesystem paths, CLI commands, and API calls where shell safety matters. The display_name handles user-facing presentation without these constraints, giving authors flexibility while preserving technical reliability.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →