Plugin developer guide
Turn an MCP Registry server.json into a Claude Code plugin
By HOL · Reviewed by Michael Kantor on
Direct answer
If your MCP server already has a server.json for the MCP Registry, hol-guard plugin package --runtimes claude-code writes a Claude Code plugin from it: .claude-plugin/plugin.json with the name, version, description and repository, and .mcp.json with the launch command. An npm package runs with npx, a PyPI package with uvx, and an OCI image with docker run. The same run can write Codex, Cursor, VS Code, Gemini CLI and OpenCode configs.
Who this is for
MCP server authors who publish to the MCP Registry and want one-step installs in agent runtimes.
Good fit
- An npm, PyPI or OCI MCP server already described in
server.json - A remote MCP server that wants a Claude Code plugin pointing at its URL
- A maintainer adding per-runtime install snippets to a README
Not a fit
- Servers with several packages in one
server.json; the Kit uses the first package - Servers that need runtime-specific flags the Registry schema cannot describe
Steps
1.Install HOL Guard
The Plugin Kit ships inside HOL Guard 3.57 and newer. It needs Python 3.10 or newer and pipx. If Guard is already installed, upgrade it, then check that
hol-guard --versionreports 3.57 or newer.pipx install hol-guard pipx upgrade hol-guard hol-guard --version2.Check server.json
The check reads
server.json, turns its first package into an MCP server entry and reports gaps such as a missing license. Environment variables listed in the package become references the user fills in.hol-guard plugin check .3.Write the Claude Code plugin
The output holds
.claude-plugin/plugin.jsonand.mcp.json. For an npm package such as@acme/notes-mcpat 2.0.1, the launch command isnpx -y @acme/[email protected], and a secret such asNOTES_TOKENis written as${NOTES_TOKEN}.hol-guard plugin package . --runtimes claude-code --out dist/hol-plugin4.Add the other runtimes
Leave out
--runtimesto write every runtime that can load an MCP server. Each config uses that runtime's environment-variable syntax.hol-guard plugin package . --out dist/hol-plugin --force5.Validate the plugin
Load the Claude Code output with Claude Code's own validator before you add it to a marketplace.
claude plugin validate dist/hol-plugin/claude-code6.Connect the repository on HOL
Open the connect page with your repository to verify ownership and claim the listing.
hol-guard plugin linksprints the same link with your repository filled in. Installing the Guard GitHub App on the repository verifies its listings automatically.hol-guard plugin links .
How a server.json package becomes a launch command
| Source or runtime | Output | Carries | Drops |
|---|---|---|---|
| npm package | npx -y <identifier>@<version> | Environment variable names | Nothing |
| PyPI package | uvx <identifier>==<version> | Environment variable names | Nothing |
| OCI image | docker run -i --rm <identifier> | Environment variable names | Nothing |
| Remote server | The remote URL | URL | Nothing |
Limitations
- Only the first package or remote in server.json is used.
- The Kit does not publish to the MCP Registry or to any marketplace. It writes files you commit or attach to a release.
- A listing or a passing check is not a safety guarantee.
Questions
Do I still need server.json if I ship a Claude Code plugin?
Keep it. The MCP Registry reads server.json, and the Kit copies your own server.json into its mcp-registry output instead of generating one.
What happens to secret environment variables?
Only the variable names are written, as references such as ${NOTES_TOKEN}. The check warns when a config ships a literal value for a variable whose name looks secret.
Can the Kit go the other way, from a plugin to server.json?
For a plugin with a single remote MCP server on GitHub, yes: the mcp-registry output is a generated server.json with a streamable HTTP remote. Package-based servers need a package identity the Kit cannot infer.
Sources
Related guides
List it on HOL
Connect the repository to verify ownership and claim the listing. New plugins can be submitted for free.