How CLI/NPM Package Plugins Distribute Their Tools in Claude
CLI and npm-based Claude plugins distribute their functional tools through a standardized .claude-plugin directory structure that bundles manifest files, skill definitions, and metadata into standard npm registries for discovery and installation via the Claude CLI.
Community and private plugins published to npm distribute their capabilities to Claude Code and Claude Cowork by embedding a specific directory layout within the package root. This approach leverages standard npm distribution mechanisms while providing the Claude runtime with deterministic metadata to locate, register, and execute tools. The anthropics/claude-plugins-community repository demonstrates this architecture through the tres-finance-plugin and other reference implementations.
The .claude-plugin Directory Structure
Every CLI-distributed Claude plugin must include a .claude-plugin directory at the package root. This hidden directory contains the complete metadata required for the plugin to function, ensuring the entire distribution is self-contained and version-controlled alongside the source code.
The directory typically contains four categories of files:
plugin.json– The primary manifest declaring plugin metadata, entry points, and tool references.marketplace.json– A pre-generated capabilities list used by the marketplace workflow to index the plugin.- Skill definitions – Markdown files under
skills/.../SKILL.mdthat specify tool inputs, outputs, and behavior. - Visual assets – Optional files such as
icon.svgfor UI representation.
When a developer runs npm publish, the entire repository—including the .claude-plugin directory and its skill markdown files—is bundled and uploaded to the registry.
Core Manifest and Configuration Files
The plugin.json Manifest
The plugin.json file serves as the runtime contract between the plugin and Claude. Located at .claude-plugin/plugin.json within the package, this JSON file declares the plugin name, version, author, and critical configuration including user secrets.
In the tres-finance-plugin implementation, the manifest declares a required secret for the DeBank API:
{
"name": "tres-finance-plugin",
"version": "1.0.0",
"secrets": ["DEBANK_API_KEY"]
}
The Claude CLI reads this manifest during installation to prompt users for sensitive configuration values, ensuring secure handling of API keys and tokens before runtime execution begins.
The marketplace.json Registry
Each plugin maintains a local .claude-plugin/marketplace.json file that enumerates its public capabilities. This file allows the marketplace ingestion workflow to aggregate tool definitions without executing arbitrary code. The consolidated registry at the repository root (anthropics/claude-plugins-community/.claude-plugin/marketplace.json) aggregates these individual manifests to make community plugins searchable and installable.
Skill Definitions as Executable Tools
Tools are not distributed as compiled binaries or scripts but as skill definition files—human-readable markdown specifications packaged with the plugin. These files reside under skills/<category>/SKILL.md paths within the .claude-plugin directory.
A skill file specifies the tool's purpose, expected inputs, and output structure. For example, the validate_balance skill in the finance plugin defines:
# Skill: validate_balance
**Description:** Checks a blockchain address balance using DeBank API.
**Inputs:**
- `address` (string) – Blockchain address.
- `network` (string) – Network name (e.g., ethereum).
**Outputs:**
- `balance` (number) – Current token balance.
At runtime, Claude parses these markdown files referenced in plugin.json to construct callable tool interfaces. This architecture separates tool specification from implementation, allowing the runtime to invoke the appropriate logic based on the skill definition.
Distribution Workflow and CLI Integration
Publishing to NPM
Plugin authors publish the complete package—including the .claude-plugin directory—to the npm registry using standard publishing workflows. The entire repository structure is preserved, ensuring that skill markdown files and manifests remain accessible at predictable paths after installation.
Installing via the Claude CLI
End users install distributed plugins through a two-step CLI workflow that mirrors standard package management patterns:
# Add the community marketplace as a source
claude plugin marketplace add anthropics/claude-plugins-community
# Install the specific plugin at the latest version
claude plugin install tres-finance-plugin@claude-community
During installation, the CLI performs the following operations:
- Pulls the package from the npm registry.
- Parses
.claude-plugin/plugin.jsonto validate metadata. - Registers each tool defined in the skill markdown files.
- Prompts the user for any secrets declared in the
secretsarray.
Once installed, tools are invoked through structured JSON requests:
{
"tool": "tres-finance-plugin.validate_balance",
"args": {
"address": "0x1234...",
"network": "ethereum"
}
}
Security and Secrets Management
The distribution model handles sensitive configuration through declarative secrets in plugin.json. Because the manifest explicitly lists required keys like DEBANK_API_KEY, the CLI can securely prompt users during installation rather than requiring manual environment variable configuration. This approach ensures that secrets are never hardcoded in the distributed package while remaining accessible to the runtime during tool execution.
Summary
- CLI and npm plugins distribute tools via a
.claude-plugindirectory at the package root containing manifests and skill definitions. plugin.jsondeclares plugin metadata and required secrets, whilemarketplace.jsonenables discoverability in the community registry.- Tools are defined in markdown skill files (
skills/*/SKILL.md) that specify inputs, outputs, and behavior without requiring compiled binaries. - The Claude CLI installs packages from npm, reads the manifest, and registers tools for invocation by Claude Code or Claude Cowork.
- User secrets are declared in the manifest and collected securely during installation, not distributed with the package.
Frequently Asked Questions
How does the Claude CLI discover tools inside an npm package?
The CLI looks for a .claude-plugin/plugin.json file at the package root after installation. This manifest contains references to skill definition markdown files under the skills/ subdirectory. The CLI parses these markdown files to understand each tool's signature and registers them as callable functions within the Claude runtime.
What files are required in the .claude-plugin directory for distribution?
A valid plugin requires at minimum plugin.json (the core manifest) and at least one skill definition file under skills/<category>/SKILL.md. The marketplace.json file is required for inclusion in the community marketplace, and optional assets like icon.svg enhance the UI presentation. All files must be committed to the repository before publishing to npm.
How does the plugin system handle API keys and sensitive configuration?
Required secrets are declared as an array in plugin.json (e.g., "secrets": ["DEBANK_API_KEY"]). When a user installs the plugin via claude plugin install, the CLI detects these declarations and prompts the user to input values securely. These values are stored in the local Claude configuration, never written to the distributed package, and injected at runtime when the corresponding tool is invoked.
Can a plugin be distributed privately without using the public npm registry?
Yes. The architecture supports any npm-compliant registry. Users can install private plugins by specifying the registry URL or using scoped packages with appropriate authentication. The .claude-plugin directory structure remains identical regardless of whether the package is published to the public npm registry or a private registry, as the Claude CLI simply executes standard npm install operations behind the scenes.
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 →