Auto-discovered marketplace from davidencrypted/portable-agent-plugin-template
npx claudepluginhub davidencrypted/portable-agent-plugin-templateA minimal example plugin with one skill and one MCP server, for verifying your setup works.
A template for packaging skills and MCP servers into a plugin that can be version-controlled in its own repo and pulled into any project as a git submodule (or installed from a marketplace).
You have skills and MCP servers that you want to reuse across multiple repos.
Dropping them directly into each project's .claude/ or equivalent folder
means duplicated files, no single source of truth, and no clean way to version
or update them. You cannot add a local skills folder from another repo as a
submodule because the expected directory structure does not allow it.
Wrap your skills and MCP servers in the plugin format. Plugins are the packaging unit that Claude Code, Copilot CLI, and GitHub Copilot in VS Code all understand, and they have a directory structure that works as a standalone repo. This means you can store your plugins in a dedicated repo and pull them into projects as a git submodule, with versioning tied to the submodule commit.
The plugin format also supports marketplace-style installation from a repo URL, so the same repo works for all three tools and both distribution methods without changes.
This template contains one example plugin with:
greeting skill -- responds when you say hello (verifies skill loading).time MCP server -- exposes get_current_time and convert_time tools
(verifies MCP loading). Uses mcp-server-time via uvx.Both exist only to confirm the install worked. Replace them with your own.
.claude-plugin/
marketplace.json # Registers repo as a marketplace (Claude Code)
.github/
plugin/
plugin.json # Direct plugin entry point (Copilot CLI / VS Code)
# MCP servers are inlined here
plugins/
example-plugin/
.claude-plugin/
plugin.json # Plugin manifest (Claude Code, via marketplace)
skills/
greeting/
SKILL.md
.mcp.json # MCP server definitions (Claude Code)
README.md
Claude Code, Copilot CLI, and GitHub Copilot in VS Code discover plugins differently. Three files cover all three tools:
| File | Read by | Purpose |
|---|---|---|
.claude-plugin/marketplace.json | Claude Code, VS Code | Registers the repo as a marketplace; points to ./plugins/example-plugin |
.github/plugin/plugin.json | Copilot CLI, VS Code | Direct plugin entry point with MCP servers inlined |
plugins/example-plugin/.claude-plugin/plugin.json | Claude Code (via marketplace) | The plugin manifest CC loads after resolving the marketplace path |
VS Code reads both .github/plugin/ and .claude-plugin/ locations, so
our layout with both is already covered.
Claude Code auto-discovers .mcp.json next to the plugin manifest, so MCP
servers are not inlined there. Copilot CLI and VS Code do not do this, so
the root-level .github/plugin/plugin.json inlines them.
This is the cost of triple compatibility. If you only target one tool, you can drop the manifests for the others.
Version-locked to a specific commit, reviewable in PRs, available to anyone who clones the repo.
git submodule add https://github.com/DavidEncrypted/portable-agent-plugin-template.git .agent-plugins/portable-agent-plugin-template
git commit -m "add agent plugin submodule"
Claude Code -- add to your project's .claude/settings.json and commit it:
{
"pluginMarketplaces": ["./.agent-plugins/portable-agent-plugin-template"],
"enabledPlugins": {
"example-plugin@portable-agent-plugin-template": true
}
}
Anyone who clones with --recurse-submodules gets prompted to enable the
plugin. Updates arrive via git submodule update.
Copilot CLI -- after cloning:
copilot plugin install ./.agent-plugins/portable-agent-plugin-template/plugins/example-plugin
After a submodule update, re-run the install. Alternatively, use
--plugin-dir for direct loading (must be passed every launch):
copilot --plugin-dir ./.agent-plugins/portable-agent-plugin-template/plugins/example-plugin
GitHub Copilot in VS Code -- the submodule method is not recommended. Plugin settings are all user-level, so a workspace-committed config won't actually enable the plugin for other users. And because the path is relative to a specific workspace, it breaks when you open a different folder. Use the marketplace install instead (see below).
Better when you want the plugin available across all projects without adding a submodule to each.
Claude Code:
claude plugin marketplace add DavidEncrypted/portable-agent-plugin-template
claude plugin install example-plugin@portable-agent-plugin-template
Copilot CLI: