Skip to content
Claude Code Mods

Publish an extension

List your Claude Code extension or mod with a pull request. A listing says the source exists, not that anyone reviewed it.

How listing works

Note

There is no submission form, account system or backend behind this site. Nothing you type here is sent anywhere.

You add one JSON file to the public repository at joeVenner/claude-code-mods (opens in a new tab) and open a pull request. Automated checks run on it, a maintainer reads it, and the site is rebuilt after it merges.

This page describes the process the repository is set up for. If the repository's own CONTRIBUTING.md differs from this page, follow that file.

From fork to listing

  1. Fork and clone the repository

    Fork the public repository on GitHub, clone your fork and start a branch. Node 22 or newer is required.

    git clone https://github.com/<your-account>/claude-code-mods.git

    cd claude-code-mods

    git switch -c add-<slug>

    npm ci

  2. Add one file

    Create src/data/community/<slug>.json. It holds a single entry, as a JSON object, and its name is the slug plus .json. Change nothing else, so that two submissions never conflict. A pull request that changes files there and files elsewhere fails a path check.

  3. Run the checks locally

    The first command runs the unit tests, which load every data file against the schema. The other two check your file against the network and are the same checks CI runs.

    npm test

    npm run catalog:verify -- --only src/data/community/<slug>.json

    npm run catalog:structure -- --only src/data/community/<slug>.json

  4. Open a pull request

    Push the branch to your fork and open a pull request against main. The template asks you to confirm each rule on this page.

  5. Wait for CI

    A workflow installs the project, runs typecheck, lint, tests and a build, then runs the two catalog checks on the file you added. A failing check names the field or the URL.

  6. A maintainer reviews and merges

    A maintainer reads every submission before merging: that its text matches the source's own words, that the links work and that the rules are met. Maintainers read the text, not the code the entry points to.

  7. The site rebuilds

    After the merge the site is built again from main. It reads the new file and the entry appears in the directory.

What a listing means

A merged pull request means the extension is listed and its source existed when the checks ran. It does not mean anyone reviewed, scanned or tested the code, and it is not an endorsement by the maintainers or by Anthropic.

The two catalog checks are narrow on purpose. The link check asks whether each URL responds. The structure check asks whether the manifest files exist and parse. Neither reads what the code does. To decide whether something is safe to install, use the checks on the Security page.

Rules every submission must meet

CI checks the shape of an entry, that its URLs respond and that its manifest files exist. It cannot prove that a command or a package is safe, and a pull request runs its own copy of the checks, so they are a convenience for contributors and not a security boundary.

A maintainer reads every submission before merging, and reads the text of the entry, not the code it points to. Merged means listed. It never means reviewed or endorsed.

The schema, the catalog loader and the checks in CI test the rules below, so most problems show up before a maintainer looks. Entries from the community appear with a visible "Community listing" label.

  • publisher.kind is "community".
  • isFeatured is false. Only maintainers feature entries.
  • stars is null. Only maintainers record star counts.
  • repositoryUrl is on github.com and responds with HTTP 200 when the check runs.
  • availability is installable or source-only, never built-in.
  • A plugin or a mod has .claude-plugin/plugin.json at the repositoryUrl location. A mod also has hooks/hooks.json with a modules array.
  • A mod lists at least one hooked event and includes a guide with a set up section and a download section, and each title contains "set up" (or "setup") and "download".
  • Every command, in installCommands, in details with isCommand true and in guide commands, is one line of printable ASCII, at most 200 characters, and has one of these forms: /plugin marketplace add <owner>/<repo>, /plugin install <name>@<marketplace>, claude --plugin-dir <path>, or git clone https://github.com/<owner>/<repo> for your own repository.
  • A download section that starts with that git clone may also use cd and git sparse-checkout set.
  • npx, curl, pipes and every other command are written as prose, never as a command.
  • No control, bidirectional or zero-width characters anywhere in the entry.
  • The publisher name does not contain anthropic, claude, official or mcp.
  • The publisher url, the verification sourceUrl and the repositoryUrl share one github.com owner, and that owner is not a reserved one.
  • verification.checkedAt is not a date in the future.
  • The slug is not too similar to a slug already in the directory.
  • Every URL is https on an allowlisted host (github.com or code.claude.com), with no credentials and no custom port.
  • One entry per file, and the file name is the slug plus .json.

What an entry contains

One file holds one entry, and it lives at src/data/community/<slug>.json. The fields below come from the schema the site validates against, so this list is the whole contract.

Identity

slug

Lowercase words joined by hyphens. It becomes the entry's address, /extensions/<slug>/.

string

In a submission: The file name is the slug plus .json. A slug already in use, or too similar to one in use, is rejected.

name

Display name shown in lists and on the entry page.

string

kind

What sort of extension this is.

plugin | skill | agent | hook | mcp-server | command | mod

categories

At least one. Drives the category filter and related entries.

array of security | workflow | development | integration | optimization | observability | sandboxing | quality | accessibility

summary

One line, 160 characters at most, shown on cards and in search.

string

description

At least one paragraph. Each item renders as its own paragraph.

array of string

Source and trust

publisher

Who publishes it. The url is an https address on an allowed host or null, and only non-null urls become links.

{ name, url, kind: anthropic | mcp-project | community }

In a submission: kind must be "community". The name may not contain anthropic, claude, official or mcp. The url, the verification sourceUrl and the repositoryUrl share one github.com owner, and that owner cannot be a reserved one.

repositoryUrl

Public source location, with no credentials in the URL. It may point at a folder inside a repository, for example a /tree/main/<folder> address.

https URL

In a submission: Must be on github.com and respond with HTTP 200.

license

License as the source states it, or null if it states none. Do not guess one.

string | null

verification

Records the date the source URL responded with HTTP 200. It says the source exists, not that anyone reviewed it.

{ status: verified, checkedAt, sourceUrl }

In a submission: checkedAt cannot be a date in the future.

stars

GitHub stars with the date they were captured.

{ count, capturedAt } | null

In a submission: Must be null. Maintainers capture star counts.

Usage and display

availability

How a person gets it. installable has documented install commands. source-only has public source and no documented install command. built-in is for things that ship inside Claude Code.

installable | built-in | source-only

In a submission: installable or source-only. built-in is reserved for maintainers.

installCommands

Commands a user can run, copied as written from the source. At least one when availability is installable, and empty otherwise.

array of string

In a submission: Each command is one line of printable ASCII, at most 200 characters, in one of the allowed forms listed under the rules. Anything else is written as prose.

notice

A caveat a reader must see before using the entry, such as early access or a required setting. Null when there is none.

string | null

details

Extra labelled facts, such as the version or how to run it from source. Set isCommand to true when the value is something to run, and the page shows it as a copyable command.

array of { label, value, isCommand }

In a submission: A value with isCommand true follows the same command rules as installCommands.

guide

Long-form explanation in reading order, as titled sections. Each section has at least one paragraph and an optional list of commands.

array of { title, paragraphs, commands }

In a submission: Required for a mod, with a section whose title contains "set up" or "setup" and one whose title contains "download". Start with an overview. Optional for other kinds. Guide commands follow the same command rules as installCommands.

hooks

Events the entry hooks, as its own source names them. A mod must list at least one.

array of string

links

Extra https links such as a README or documentation page, on github.com or code.claude.com.

array of { label, url }

tags

Free-form keywords used by search.

array of string

isFeatured

Places the entry at the front of the catalog order.

boolean

In a submission: Must be false. Only maintainers feature entries.

An example entry

Example, not a real listing. The slug example-format-on-save, the publisher and every URL in it are invented, and the link check would report them as not found.
{
  "slug": "example-format-on-save",
  "name": "Example Format on Save",
  "kind": "plugin",
  "categories": [
    "quality"
  ],
  "summary": "Runs a formatter after each file edit and reports failures back to the session.",
  "description": [
    "One paragraph per array item. Say what it does, what it needs, and anything a user should check first."
  ],
  "publisher": {
    "name": "Example publisher",
    "url": "https://github.com/example-publisher",
    "kind": "community"
  },
  "repositoryUrl": "https://github.com/example-publisher/example-format-on-save",
  "license": "MIT",
  "availability": "source-only",
  "installCommands": [],
  "notice": null,
  "details": [
    {
      "label": "Formatter",
      "value": "Any formatter on your PATH",
      "isCommand": false
    }
  ],
  "guide": [],
  "hooks": [
    "PostToolUse"
  ],
  "tags": [
    "formatting"
  ],
  "links": [
    {
      "label": "README",
      "url": "https://github.com/example-publisher/example-format-on-save/blob/main/README.md"
    }
  ],
  "stars": null,
  "isFeatured": false,
  "verification": {
    "status": "verified",
    "checkedAt": "2026-01-15",
    "sourceUrl": "https://github.com/example-publisher/example-format-on-save"
  }
}

A guide is a list of titled sections, each with paragraphs and optional commands. For a mod it is required, with at least an overview, a setup section and a download section. The sections below are invented and belong to no real mod.

Example guide, not from a real mod.
[
  {
    "title": "Overview",
    "paragraphs": [
      "What the mod does, which events it hooks and what a person will notice when it is loaded."
    ],
    "commands": []
  },
  {
    "title": "Setup",
    "paragraphs": [
      "What has to be enabled first, and how to load the mod from a local folder."
    ],
    "commands": [
      "claude --plugin-dir example-hook-mod"
    ]
  },
  {
    "title": "Download",
    "paragraphs": [
      "Where the source lives and how to get it."
    ],
    "commands": [
      "git clone https://github.com/example-publisher/example-hook-mod"
    ]
  }
]

If your entry is a mod

A mod is a Claude Code plugin whose behaviour lives in a hooks module. Anthropic's own mods are described in the mods README (opens in a new tab), and the typings the engine offers them are in the mods types folder (opens in a new tab). Use only event names you find there.

You load a mod from a local folder, and test it, with these commands. Function hooks must be enabled for a hooks module to load. In an entry, only the first form is allowed as a command, so describe testing in prose.

claude --plugin-dir <path-to-mod>

claude plugin test <path-to-mod>

Warning

Early access. The API mods are written against may change between Claude Code releases without notice, and mods are not listed in a plugin marketplace. Say so in the entry's notice.

Open item: license for submitted data

This repository has no LICENSE file yet. The maintainer will decide the license that applies to submitted data. Until that is decided, do not assume one.

How plugins are packaged

This site does not package or host anything. Claude Code documents how plugins and plugin marketplaces are built and distributed, and that documentation is the source to follow.