I spent an afternoon turning a GitHub repo into a Claude plugin marketplace.
The docs get you 80% there. The last 20% is where I burned two hours, so
here's the setup plus the two gotchas that aren't written down anywhere.
The structure
Two files matter:
.claude-plugin/marketplace.json <- the catalog
plugins/opula/plugin.json <- one entry per plugin
marketplace.json lists what's in the repo. Each plugin points to its own
plugin.json, which declares name, version, and (if it ships an MCP server)
an .mcp.json pointing at a remote HTTP endpoint. Mine authenticates via
Dynamic Client Registration, so there's no API key to hand out. Anyone who
installs it goes through OAuth on first connect.
Installing it
Two lines, from inside Claude Code:
/plugin marketplace add evan-moon/opula-plugin
/plugin install opula@opula
That's it. No forking, no local clone.
Gotcha 1: two version numbers, one sync you can't see
plugin.json and marketplace.json both carry a version. Bump one and
forget the other, and Claude Code will happily install the stale one with no
error. Worse: claude.ai's marketplace sync is manual on top of that, so a
fix you shipped an hour ago might not reach anyone who installs through the
web client until you go trigger the sync yourself. Claude Code gives you
zero visibility into this step. You just have to remember it exists.
Gotcha 2: installed but "broken"
If someone installs the plugin but never connects the underlying MCP
server, they'll see the skills load fine and then hit a wall the moment a
skill tries to call a tool. Nothing crashes, nothing errors clearly, it just
looks broken. The fix is a connection step, not a bug fix, but nothing in
the UI tells you that's what's missing. If you're shipping a plugin with an
MCP backend, put the "go connect it" instruction directly in your first
skill's output, not just in the README.
What the skills are actually doing
Worth saying out loud: the 6 skills in this plugin aren't a smarter model
bolted on top. They're routing. analyze-holding walks a fixed catalog of
checks instead of freestyling an analysis. month-end asks a clarifying
question up front if data's missing instead of guessing. import-ledger
confirms the column mapping before it writes anything. None of that is
"AI reasoning" in any interesting sense, it's just structure that keeps the
model from improvising in places where improvising is the wrong move.
Token cost, since nobody publishes this
Rough numbers, not exact: always-on context from the plugin lands around
1k tokens, every turn, whether you use it or not. Per-skill invocation adds
roughly 1.5k-2k depending on which one fires and how much markdown/code
gets pulled in. I'm rounding these on purpose, if you're building one of
these, run /context in a session with the plugin installed and get your
own real numbers rather than trusting mine.
This is the plugin for opula,
a portfolio copilot I built for tracking holdings across multiple brokers.
The plugin adds 6 skills on top of the existing MCP connector; same account,
Pro plan or above. If you hit either gotcha above while setting up your own
marketplace, I'd genuinely like to hear about it.
Top comments (0)