Documentation Index
Fetch the complete documentation index at: https://mintlify.com/vercel-labs/skills/llms.txt
Use this file to discover all available pages before exploring further.
The Skills CLI supports skill discovery from Claude Code plugin manifests, enabling compatibility with the Claude Code plugin marketplace ecosystem.
Overview
Plugin manifests allow you to:
- Declare skills explicitly instead of relying on directory conventions
- Group multiple skills under a named plugin
- Define multi-plugin repositories (marketplace catalogs)
- Maintain compatibility with Claude Code’s plugin system
Plugin manifests are optional. The CLI will still discover skills in standard locations even without manifests.
Supported Manifest Files
The CLI looks for these files in a repository:
marketplace.json
Multi-plugin catalog
Location: .claude-plugin/marketplace.json
plugin.json
Single plugin
Location: .claude-plugin/plugin.json
Marketplace Manifest
A marketplace manifest defines multiple plugins in a single repository.
File Location
.claude-plugin/marketplace.json
Schema
{
"metadata": {
"pluginRoot": "./plugins"
},
"plugins": [
{
"name": "document-skills",
"source": "./document-tools",
"skills": [
"./skills/markdown-formatter",
"./skills/doc-generator"
]
},
{
"name": "web-skills",
"source": "./web-tools",
"skills": [
"./skills/react-best-practices"
]
}
]
}
Fields
Global metadata for the marketplace
Base directory for all plugins. Must start with ./ (relative path)Example: "./plugins"
Array of plugin definitions
Plugin name for grouping skills (e.g., "document-skills")This name is stored in the lock file’s pluginName field.
Plugin location:
- String: Relative path starting with
./ (e.g., "./my-plugin")
- Object: Remote source with
source and optional repo fields (skipped by CLI)
The CLI only processes local string paths. Array of skill paths relative to the plugin directory. Each path must start with ./Example: ["./skills/formatter", "./skills/validator"]
Path Resolution
Paths are resolved in this order:
- Start with repository root
- Apply
metadata.pluginRoot if present
- Apply
plugin.source if present
- Apply each skill path from
plugin.skills
// Given this manifest:
{
"metadata": { "pluginRoot": "./plugins" },
"plugins": [
{
"source": "./document-tools",
"skills": ["./skills/formatter"]
}
]
}
// Skill path resolves to:
// {repo_root}/plugins/document-tools/skills/formatter/SKILL.md
Plugin Manifest
A plugin manifest defines a single plugin at the repository root.
File Location
.claude-plugin/plugin.json
Schema
{
"name": "my-plugin",
"skills": [
"./skills/react-best-practices",
"./skills/typescript-guide"
]
}
Fields
Plugin name for grouping skills
Array of skill paths relative to the repository root. Each path must start with ./
Path Resolution
Paths are resolved relative to the repository root:
// Given this manifest:
{
"name": "my-plugin",
"skills": ["./skills/formatter"]
}
// Skill path resolves to:
// {repo_root}/skills/formatter/SKILL.md
Security: Path Validation
All paths in plugin manifests are validated to prevent path traversal attacks.
Validation Rules
Relative path check
All paths must start with ./ per the Claude Code convention
Containment check
Resolved paths must be contained within the repository root (no .. segments allowed)
Normalization
Paths are normalized before checking containment
Invalid Paths
{
"skills": [
"../../../etc/passwd", // ❌ Path traversal
"/absolute/path", // ❌ Absolute path
"relative/path", // ❌ Missing ./
"./skills/../../../etc" // ❌ Escapes repo root
]
}
How Discovery Works
When you run skills add <source>, the CLI searches for skills in this order:
Check for manifests
Look for .claude-plugin/marketplace.json or .claude-plugin/plugin.json
Extract declared skills
If manifests exist, add their skill paths to the search list
Add conventional directories
Always search standard locations like skills/, .agents/skills/, etc.
Discover SKILL.md files
Find all SKILL.md files in the search directories
Deduplicate
Remove duplicate skills based on normalized name
Discovery Flow
Plugin Grouping
Skills discovered from manifests can be grouped by plugin name.
In Lock Files
When a skill is installed from a manifest with a name field, the plugin name is stored:
{
"skills": {
"markdown-formatter": {
"source": "owner/repo",
"sourceType": "github",
"pluginName": "document-skills", // ← From manifest
"skillFolderHash": "abc123..."
}
}
}
In Skill Lists
The skills list command can group skills by plugin:
$ skills list
Project Skills (.agents/skills/)
document-skills
• markdown-formatter
• doc-generator
web-skills
• react-best-practices
(ungrouped)
• standalone-skill
Implementation Details
Source Code
Plugin manifest support is implemented in src/plugin-manifest.ts:
import { getPluginSkillPaths, getPluginGroupings } from './plugin-manifest';
// Get skill search directories from manifests
const searchDirs = await getPluginSkillPaths('/path/to/repo');
// Returns: [
// '/path/to/repo/plugins/document-tools/skills/formatter',
// '/path/to/repo/skills', // conventional fallback
// ...
// ]
// Get plugin name for each skill path
const groupings = await getPluginGroupings('/path/to/repo');
// Returns: Map<AbsolutePath, PluginName>
// Example: Map {
// '/abs/path/to/skill' => 'document-skills'
// }
API
Extract skill search directories from plugin manifests
async function getPluginSkillPaths(basePath: string): Promise<string[]>
Repository root directory
Array of absolute paths to directories containing skills
Get a map of skill paths to plugin names
async function getPluginGroupings(basePath: string): Promise<Map<string, string>>
Repository root directory
Map of absolute skill path to plugin name
Examples
Basic Marketplace
{
"plugins": [
{
"name": "core-skills",
"skills": [
"./skills/formatter",
"./skills/validator"
]
}
]
}
Marketplace with Plugin Root
{
"metadata": {
"pluginRoot": "./packages"
},
"plugins": [
{
"name": "web-tools",
"source": "./web",
"skills": ["./skills/react"]
},
{
"name": "api-tools",
"source": "./api",
"skills": ["./skills/rest"]
}
]
}
Simple Plugin
{
"name": "typescript-guide",
"skills": [
"./skills/setup",
"./skills/best-practices",
"./skills/testing"
]
}
Lock Files
See how pluginName is stored in lock files
Claude Code Plugins
Learn about the Claude Code plugin marketplace