# How to Specify a Plugin Source from a Git Subdirectory in the Claude Plugins Community

> Learn to specify a plugin source from a Git subdirectory using the git-subdir type in your manifest. Point to specific subfolders in the anthropics/claude-plugins-community repo with ease.

- Repository: [Anthropic/claude-plugins-community](https://github.com/anthropics/claude-plugins-community)
- Tags: how-to-guide
- Published: 2026-09-04

---

**Use the `git-subdir` source type in the manifest's `source` object and provide the repository URL, relative path, and optional Git ref or pinned SHA to point to a plugin located inside a subdirectory.**

The Claude Plugins Community repository (`anthropics/claude-plugins-community`) manages plugin entries through a centralized manifest system. When your plugin code lives inside a subdirectory rather than at the repository root, you must declare this location using a specific JSON schema that the validation CI recognizes. This guide explains the exact manifest fields and validation logic used to specify a plugin source from a Git subdirectory.

## Understanding the git-subdir Source Type

The **manifest file** ([`.claude-plugin/marketplace.json`](https://github.com/anthropics/claude-plugins-community/blob/main/.claude-plugin/marketplace.json)) serves as the single source of truth for all community plugins. For plugins not residing at the root of a Git repository, the `source` object must declare `"source": "git-subdir"` to signal that the plugin files are nested within a subfolder. This distinction tells the **Validate‑Plugins** GitHub Action to perform additional path resolution and SHA verification steps during the CI pipeline.

## Required Manifest Fields for Git Subdirectory Sources

When configuring a `git-subdir` entry in the marketplace manifest, include these specific fields:

- **`source`**: Must be the string `"git-subdir"` to activate subdirectory mode.
- **`url`**: Either the shorthand `owner/repo` format or a full HTTPS URL to the Git repository.
- **`path`**: The directory path relative to the repository root containing the plugin's [`plugin.json`](https://github.com/anthropics/claude-plugins-community/blob/main/plugin.json) or [`SKILL.md`](https://github.com/anthropics/claude-plugins-community/blob/main/SKILL.md).
- **`ref`** *(optional)*: The Git reference (branch name, tag, or commit) to checkout. Defaults to `main` if omitted.
- **`sha`** *(optional but recommended)*: A pinned 40-character commit SHA that the CI validates against the resolved ref to guarantee reproducibility.

## How CI Validation Works for Subdirectory Sources

The validation logic resides in [`.github/actions/validate-plugins/scripts/30-validate-cli-external.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/actions/validate-plugins/scripts/30-validate-cli-external.sh) and executes the following sequence:

1. Clones the repository specified in the `url` field.
2. Checks out the `ref` (or directly uses the `sha` if provided for verification).
3. Verifies that the `path` exists within the cloned repository structure.
4. If a `sha` is present, confirms that the checkout's HEAD matches the pinned SHA exactly.

If any step fails, the plugin entry is rejected from the marketplace.

## Code Examples

### Minimal Configuration Without SHA Pinning

Use this approach for development or when you want the plugin to track a moving tag or branch:

```json
{
  "name": "example-plugin",
  "description": "Demo plugin from a subdirectory",
  "source": {
    "source": "git-subdir",
    "url": "owner/example-repo",
    "path": "plugins/example",
    "ref": "v2.1.0"
  },
  "homepage": "https://github.com/owner/example-repo"
}

```

The CI clones `owner/example-repo`, fetches tag `v2.1.0`, and validates that `plugins/example` exists. Without a `sha`, the plugin content can change if the tag is moved.

### Production Configuration With Pinned SHA

For reproducible builds and security, pin the exact commit hash:

```json
{
  "name": "secure-plugin",
  "description": "Uses a fixed commit for reproducibility",
  "source": {
    "source": "git-subdir",
    "url": "https://github.com/org/secure-repo.git",
    "path": "plugins/secure",
    "ref": "main",
    "sha": "a1b2c3d4e5f67890123456789abcdef012345678"
  },
  "homepage": "https://github.com/org/secure-repo"
}

```

The validation script checks out `main`, then verifies that the HEAD commit matches `a1b2c3d4e5f67890123456789abcdef012345678` before accepting the subdirectory content.

### Validating Locally Before Submission

Mirror the CI checks locally using the validation script to catch errors early:

```bash

# Run the same validation logic used by the GitHub Action

bash .github/actions/validate-plugins/scripts/30-validate-cli-external.sh \
    --name example-plugin \
    --source "$(cat entry.json)"

```

This script uses helper utilities from [`.github/actions/validate-plugins/lib/common.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/actions/validate-plugins/lib/common.sh) (including path safety checks) to ensure your `git-subdir` configuration is valid before pushing to the repository.

## Key Source Files in the Repository

Understanding these files helps when debugging subdirectory configuration issues:

- **[`.claude-plugin/marketplace.json`](https://github.com/anthropics/claude-plugins-community/blob/main/.claude-plugin/marketplace.json)**: The central manifest where `git-subdir` entries are registered (see lines 57‑84 for examples).
- **[`.github/actions/validate-plugins/scripts/30-validate-cli-external.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/actions/validate-plugins/scripts/30-validate-cli-external.sh)**: The CI script that handles cloning, ref resolution, and SHA verification for subdirectory sources.
- **[`.github/actions/validate-plugins/lib/common.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/actions/validate-plugins/lib/common.sh)**: Provides utility functions like `assert_safe_path` used during validation.
- **[`.github/actions/bump-plugin-shas/scripts/bump.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/actions/bump-plugin-shas/scripts/bump.sh)**: Automates updating pinned SHAs for `git-subdir` entries during release workflows.

## Summary

- Set `"source": "git-subdir"` in the manifest to indicate a subdirectory location.
- Provide the repository `url` and relative `path` to the plugin files.
- Use the `ref` field to specify a branch or tag, defaulting to `main`.
- Pin a `sha` for reproducible builds and enhanced security.
- The CI validation enforces existence of the path and SHA/ref consistency before accepting entries.

## Frequently Asked Questions

### What happens if the path does not exist in the repository?

The **Validate‑Plugins** action rejects the entry. Specifically, the script [`30-validate-cli-external.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/30-validate-cli-external.sh) verifies path existence after cloning, and if the subdirectory is missing, the validation fails with an error message indicating the path was not found.

### Can I use a private Git repository as a git-subdir source?

The current implementation in the `anthropics/claude-plugins-community` repository assumes public repositories accessible via HTTPS. The validation scripts do not include authentication logic for private repositories in the standard CI workflow.

### How do I update the pinned SHA for my plugin?

Use the automated bump workflow or manually edit the `sha` field in [`.claude-plugin/marketplace.json`](https://github.com/anthropics/claude-plugins-community/blob/main/.claude-plugin/marketplace.json). The [`bump.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/bump.sh) script (located at [`.github/actions/bump-plugin-shas/scripts/bump.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/actions/bump-plugin-shas/scripts/bump.sh)) can automatically fetch the latest commit from your specified `ref` and update the SHA field to maintain reproducibility while pulling in updates.

### Is the ref field required if I provide a SHA?

No, the `ref` field is optional, but providing it improves readability and ensures the CI checks out the correct branch before verifying the SHA. If omitted, the validation defaults to `main`, which may cause failures if your pinned SHA exists only on a different branch.