What Are the Requirements for Building a Claude Plugin? A Developer's Guide
Building a Claude plugin requires a valid plugin.json manifest with mandatory metadata fields, a standard directory layout including a skills/ folder, semantic versioning, and successful passage through the CI validation workflow defined in the anthropics/claude-plugins-community repository.
The anthropics/claude-plugins-community repository defines the official specification for creating distributable extensions for Claude Code and Claude Cowork. To build a Claude plugin that can be discovered and installed by the platform, developers must satisfy a strict architectural contract covering manifest format, file structure, and automated validation.
Mandatory Manifest File Structure
Every Claude plugin must contain a JSON manifest named plugin.json. As implemented in the reference examples, this file can reside at the repository root or inside a hidden .claude-plugin/ folder, with the nested location taking precedence if both exist.
The manifest supplies essential metadata that the platform uses to list, install, and validate the plugin. The CI workflow defined in .github/workflows/validate-plugins.yml automatically rejects any submission lacking this file.
Required Metadata Fields
The plugin.json manifest must include specific keys that are validated by the CI checks:
- name – The unique plugin identifier
- description – Human-readable summary of functionality
- version – Must follow semantic versioning (
MAJOR.MINOR.PATCH) - author – Object containing
nameand optionallyemail - homepage – URL to the project page
- repository – Source code repository URL
- license – Valid SPDX-compatible identifier
- keywords – Array of descriptive strings
The validation logic verifies these fields against the schema demonstrated in testdino/.claude-plugin/plugin.json.
Standard Directory Layout
The platform automatically scans specific directories to discover plugin capabilities. According to the plugin discovery description in .github/actions/scan-plugins/policy/prompt.md, the standard structure includes:
skills/– Contains skill definitions, where each skill is a folder with aSKILL.mdfile and optional auxiliary assets.agents/– Optional agents for multi-step interactions.commands/– Optional custom commands.hooks/– Optional local or remote hooks.
The skills/ directory is essential for functional plugins, as it houses the human-readable skill definitions that Claude uses to understand invocation patterns.
Optional MCP Server Configuration
If your Claude plugin requires remote MCP (Model Context Protocol) servers, you must declare them in a .mcp.json file or inside plugin.json under the top-level key mcpServers. Each server object must contain:
- url – The endpoint address
- command – The shell command used to start the server
The validation script at .github/actions/scan-plugins/lib/pin-check.sh specifically checks for the presence and structure of these mcpServers declarations during the CI process.
Versioning and Licensing Standards
The version field in plugin.json must follow strict semantic versioning (MAJOR.MINOR.PATCH). The CI workflow executes the version bump validation script at .github/actions/bump-plugin-shas/scripts/bump.sh to ensure version consistency across the marketplace file and prevent invalid version strings.
Additionally, the license field must contain a valid SPDX-compatible identifier, enabling the marketplace to display accurate licensing information for every published extension.
Marketplace Registration and CI Validation
For a Claude plugin to appear in the public marketplace, the repository must contain a top-level .claude-plugin/marketplace.json file that lists each plugin's path. The CI workflow auto-generates and validates this file, referencing entries like those found at line 6662 of the marketplace registry.
Every pull request triggers the validate-plugins.yml GitHub Action, which performs the following checks:
- Verifies that
plugin.jsonexists at the root or in.claude-plugin/ - Validates that all required fields are present and correctly typed
- Ensures JSON is well-formed
- Confirms that any declared
mcpServersare correctly structured
A plugin that fails any validation step cannot be merged into the community repository.
Minimum Viable Plugin Example
Below is a fully compliant Claude plugin structure that satisfies all architectural requirements:
my-awesome-plugin/
├─ .claude-plugin/
│ └─ plugin.json
├─ skills/
│ └─ hello-world/
│ ├─ SKILL.md
│ └─ hello_world.py
└─ .mcp.json
plugin.json
{
"name": "my-awesome-plugin",
"description": "A simple example plugin that says hello.",
"version": "0.1.0",
"author": { "name": "Your Name", "email": "you@example.com" },
"homepage": "https://github.com/your-org/my-awesome-plugin",
"repository": "https://github.com/your-org/my-awesome-plugin",
"license": "MIT",
"keywords": ["claude-plugin", "example"]
}
SKILL.md
# Hello World Skill
## Description
Returns a friendly greeting.
## Command
`/my-awesome-plugin:hello`
## Implementation
```python
def run():
return "👋 Hello from my-awesome-plugin!"
```
Optional MCP Configuration (.mcp.json)
{
"mcpServers": {
"default": {
"url": "http://localhost:8080",
"command": "node server.js"
}
}
}
Running the CI workflow locally or via GitHub Actions confirms that the plugin meets every requirement for building a Claude plugin that can be published and distributed.
Summary
Building a Claude plugin requires satisfying a strict contract defined by the anthropics/claude-plugins-community repository:
- Manifest requirement: A
plugin.jsonfile containingname,description,version,author,homepage,repository,license, andkeywordsfields, located at the repository root or in.claude-plugin/. - Directory structure: A mandatory
skills/directory containingSKILL.mdfiles, plus optionalagents/,commands/, andhooks/folders scanned by the platform. - Server integration: Optional MCP servers declared via
.mcp.jsonor themcpServerskey, validated by.github/actions/scan-plugins/lib/pin-check.sh. - Version compliance: Semantic versioning enforced by the bump script at
.github/actions/bump-plugin-shas/scripts/bump.sh. - Marketplace registration: Automatic entry in
.claude-plugin/marketplace.jsongenerated by the CI workflow. - Automated validation: Successful passage through
.github/workflows/validate-plugins.ymlchecking manifest presence, field compliance, and JSON validity.
Frequently Asked Questions
Where must the plugin.json file be located?
The plugin.json manifest can reside at the repository root or inside a .claude-plugin/ hidden directory. If both locations contain the file, the version inside .claude-plugin/ takes precedence during the discovery process, as documented in the repository's validation logic.
What happens if my plugin fails CI validation?
If the GitHub Action defined in .github/workflows/validate-plugins.yml detects missing required fields, malformed JSON, or invalid mcpServers configurations, the pull request will be blocked from merging. The plugin cannot be published to the marketplace until all validation checks pass.
Is semantic versioning strictly enforced for Claude plugins?
Yes. The version field must follow the MAJOR.MINOR.PATCH format. The CI workflow runs a validation script from .github/actions/bump-plugin-shas/scripts/bump.sh that checks version consistency and rejects non-compliant version strings before they reach the marketplace.
Do I need to manually create the marketplace.json file?
No. The .claude-plugin/marketplace.json file is auto-generated by the CI workflow. Developers only need to ensure their plugin.json is correctly placed; the validation pipeline automatically updates the marketplace registry with the plugin's path and metadata.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →