# Understanding the `.claude-plugin/plugin.json` Manifest Format for Claude Code Plugins

> Discover the `.claude-plugin/plugin.json` manifest format. Learn how this file declares Claude Code plugin identity, metadata, and runtime configuration for your repository.

- Repository: [Anthropic/claude-plugins-community](https://github.com/anthropics/claude-plugins-community)
- Tags: api-reference
- Published: 2026-09-08

---

**The [`.claude-plugin/plugin.json`](https://github.com/anthropics/claude-plugins-community/blob/main/.claude-plugin/plugin.json) file is the canonical manifest that declares a Claude Code plugin's identity, metadata, and runtime configuration within a hidden `.claude-plugin` directory at the repository root.**

This JSON file serves as the single source of truth consumed by the Claude CLI, the marketplace UI, and validation CI jobs. Located at [`/.claude-plugin/plugin.json`](https://github.com/anthropics/claude-plugins-community/blob/main//.claude-plugin/plugin.json) (or optionally [`plugin.json`](https://github.com/anthropics/claude-plugins-community/blob/main/plugin.json) at the repo root), it defines everything from the plugin's display name to sensitive user configuration variables.

## Core Schema Fields

The manifest follows a declarative schema where only the `name` field is strictly required. All other fields provide optional metadata or advanced runtime capabilities.

### Required Fields

**`name`** (string, required): The human-readable identifier used throughout the ecosystem. This value becomes the command prefix in the Claude CLI (e.g., `/my-plugin:skill`) and the display title in the marketplace catalog.

### Metadata Fields

**`description`** (string): Short free-form text displayed in the plugin catalog to help users understand functionality.

**`version`** (string, semver): Follows *MAJOR.MINOR.PATCH* semantics (e.g., `"1.12.1"`). Displayed to users in the marketplace and CLI.

**`author`** (object): Contains `name` (string) and optionally `email` (string) for attribution.

**`homepage`** (string, URL): Link to public documentation or marketing pages.

**`repository`** (string, URL): Source repository URL used by the marketplace for "View source" functionality.

**`license`** (string): SPDX identifier such as `"MIT"` or `"Apache-2.0"`.

**`keywords`** (array[string]): Discovery tags that improve searchability in the marketplace (e.g., `["blockchain", "accounting"]`).

### Configuration Fields

**`userConfig`** (object): Defines configuration variables that users set during installation. Each key maps to an object containing:

- **`title`** – UI label shown to users
- **`description`** – Help text explaining the variable's purpose
- **`type`** – JSON schema type (`string`, `number`, `boolean`)
- **`sensitive`** (boolean) – When `true`, the value is masked in the UI and never logged, ensuring secrets like API keys remain encrypted in Claude's secret store

### Advanced Features

**`mcpServers`** (array[object]): Declares hosted MCP (Model Context Protocol) servers the plugin calls. Each server object includes `command`, `url`, and `auth` properties. The marketplace parses this to generate runtime shims, validating that `command` values do not clash with internal commands to prevent namespace collisions.

**Implementation directories**: While not part of the JSON schema itself, the presence of `commands/`, `skills/`, `agents/`, or `hooks/` directories alongside the manifest signals the plugin's surface area to the scanner.

## Manifest Discovery and Validation

The Claude ecosystem uses specific validation logic to locate and verify manifests. In [`.github/actions/validate-plugins/lib/common.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/actions/validate-plugins/lib/common.sh), the CI action looks for the manifest at lines 154-158, checking both [`/.claude-plugin/plugin.json`](https://github.com/anthropics/claude-plugins-community/blob/main//.claude-plugin/plugin.json) and [`/plugin.json`](https://github.com/anthropics/claude-plugins-community/blob/main//plugin.json) at the repository root.

When a plugin is configured with `strict:false`, the validation logic at lines 162-163 synthesizes a minimal manifest automatically, generating only `{ "name": "<plugin-name>" }` to satisfy requirements without manual authoring.

The scanning workflow in [`.github/actions/scan-plugins/scripts/scan.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/actions/scan-plugins/scripts/scan.sh) reads the manifest alongside [`.mcp.json`](https://github.com/anthropics/claude-plugins-community/blob/main/.mcp.json) and implementation directories to build the complete marketplace descriptor. During CI, [`.github/actions/validate-plugins/scripts/40-validate-cli-local.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/actions/validate-plugins/scripts/40-validate-cli-local.sh) executes `claude plugin validate` to reject unknown keys and enforce type constraints.

## Practical Examples

### Minimal Manifest

For simple plugins that require no configuration or metadata beyond the name:

```json
{
  "name": "hello-world",
  "version": "0.1.0"
}

```

The CLI accepts this minimal definition, though the marketplace will display no description, keywords, or configuration options.

### Full-Featured Manifest with User Configuration

This real-world example from the `tres-finance-plugin` demonstrates metadata richness and secure configuration handling:

```json
{
  "name": "tres-finance-plugin",
  "description": "Blockchain accounting workflows, ledger management, and transaction analysis.",
  "version": "1.12.1",
  "author": {
    "name": "Nadav Gilliam",
    "email": "nadav@tres.finance"
  },
  "homepage": "https://tres.finance",
  "repository": "https://github.com/Tres-Finance-Public/tres-claude-plugin",
  "license": "MIT",
  "keywords": [
    "tres-finance",
    "blockchain",
    "accounting",
    "ledger",
    "crypto"
  ],
  "userConfig": {
    "DEBANK_API_KEY": {
      "title": "DeBank API Key",
      "description": "Your DeBank Pro API key for balance validation (from https://cloud.debank.com)",
      "type": "string",
      "sensitive": true
    }
  }
}

```

The `sensitive: true` flag ensures the DeBank API key remains encrypted and never appears in logs or CLI output.

### Advanced MCP Server Declaration

For plugins requiring remote server integration:

```json
{
  "name": "my-mcp-plugin",
  "mcpServers": [
    {
      "command": "my-mcp:run",
      "url": "https://mcp.myservice.com",
      "auth": {
        "type": "bearer",
        "envVar": "MY_MCP_TOKEN"
      }
    }
  ]
}

```

This instructs the marketplace to generate a shim that forwards `my-mcp:run` invocations to the specified endpoint, using the bearer token stored in the `MY_MCP_TOKEN` environment variable.

## Summary

- The [`.claude-plugin/plugin.json`](https://github.com/anthropics/claude-plugins-community/blob/main/.claude-plugin/plugin.json) manifest lives in a hidden `.claude-plugin` directory and defines plugin identity, metadata, and runtime behavior.
- Only the `name` field is strictly required; all other fields provide optional marketplace visibility or configuration capabilities.
- The `userConfig` object supports sensitive values through the `sensitive` boolean flag, which triggers encryption and log masking.
- CI validation in [`.github/actions/validate-plugins/lib/common.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/actions/validate-plugins/lib/common.sh) locates the manifest and synthesizes minimal versions when `strict:false` is set.
- The `mcpServers` array enables advanced integrations with hosted MCP endpoints while preventing command namespace collisions.

## Frequently Asked Questions

### Is the `name` field the only required field in [`.claude-plugin/plugin.json`](https://github.com/anthropics/claude-plugins-community/blob/main/.claude-plugin/plugin.json)?

Yes. According to the validation logic in [`.github/actions/validate-plugins/lib/common.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/actions/validate-plugins/lib/common.sh), only the `name` field is mandatory. If you omit optional fields, the plugin will still function, though the marketplace will display limited information and users cannot configure runtime variables.

### How does the `sensitive` flag in `userConfig` protect my API keys?

When you set `sensitive: true` on a configuration variable, Claude's secret store encrypts the value and ensures it never appears in CLI logs, UI displays, or debug output. This is essential for storing API keys and authentication tokens securely while still making them available to your plugin's runtime environment.

### Where should I place the [`.claude-plugin/plugin.json`](https://github.com/anthropics/claude-plugins-community/blob/main/.claude-plugin/plugin.json) file in my repository?

Place it inside a hidden `.claude-plugin` directory at the repository root (i.e., [`/.claude-plugin/plugin.json`](https://github.com/anthropics/claude-plugins-community/blob/main//.claude-plugin/plugin.json)). Alternatively, the validator accepts [`plugin.json`](https://github.com/anthropics/claude-plugins-community/blob/main/plugin.json) directly at the root, but the hidden directory approach is preferred for cleaner repository organization and aligns with the scanner logic in [`.github/actions/scan-plugins/scripts/scan.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/actions/scan-plugins/scripts/scan.sh).

### What happens if my plugin doesn't have a manifest file?

If you enable `strict:false` mode, the CI validation logic at lines 162-163 of [`.github/actions/validate-plugins/lib/common.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/actions/validate-plugins/lib/common.sh) automatically synthesizes a minimal manifest containing only `{ "name": "<plugin-name>" }`. However, without a full manifest, you cannot define `userConfig`, `mcpServers`, or marketplace metadata, significantly limiting discoverability and functionality.