#4825: Russian Dolls: Skills, MCPs, and Plugins

When to use a skill vs MCP vs plugin in Claude Code — and when to keep it simple.

Featuring
Listen
0:00
0:00
Episode Details
Episode ID
MWP-5004
Published
Duration
28:56
Audio
Direct link
Pipeline
V5
TTS Engine
chatterbox-regular
Script Writing Agent
deepseek-v4-pro

AI-Generated Content: This podcast is created using AI personas. Please verify any important information independently.

Claude Code's plugin architecture is a set of three nested layers, each with a distinct purpose. At the innermost level are tool definitions — individual capabilities like "get a pull request" or "create an issue." These live inside MCPs (Model Context Protocol), which connect the agent to external services. The outermost layer is the plugin itself — a self-contained directory with a plugin.json manifest, a skills subdirectory, and an MCP subdirectory that bundles everything together.

The key decision point is reuse frequency. A single skill defined directly in your project's CLAUDE.md has zero overhead and works identically to one imported from a plugin. The heuristic to extract into a plugin is when you've copied the same pattern into a third project. For teams, plugins enforce consistency — everyone gets the same version of every skill and MCP.

Token efficiency is a real concern. Every declared MCP consumes context window space, even if its tools are never called. The plugin specification's requires field is all-or-nothing — no support for optional MCPs or conditional loading. The community is developing conventions around minimal MCP surfaces, semantic versioning, and graceful degradation when required tools are unavailable. Security is another open question: the official Anthropic registry has a verification process, but npm-published plugins have no such gate, and the plugin format currently lacks a permissions model.

Downloads

Episode Audio

Download the full episode as an MP3 file

Download MP3
Transcript (TXT)

Plain text transcript file

Transcript (PDF)

Formatted PDF with styling

#4825: Russian Dolls: Skills, MCPs, and Plugins

Corn
Every Claude Code user I know has a folder somewhere — a CLAUDE.md file, some custom slash commands, maybe a half-dozen MCP configs they copied between projects — and no clear rule for when to stop copy-pasting and build a plugin. Daniel's been living in exactly this mess, and he's put together a mental model that actually clarifies it. He describes it as Russian dolls. The plugin is the big outer doll. Inside that, an MCP — which itself contains tool definitions, the smallest doll. But here's the question he's really asking: when do you need the big doll at all? Sometimes a couple of one-off skills in your repo is the right call. As these frameworks go mainstream, he wants us to walk through the pros, the cons, and the decision boundary.
Herman
And the timing's right for this. The plugin registry just went live on the Anthropic docs site, the specification is public, and people are already publishing packages to npm. We're at the exact moment where the patterns are forming but haven't hardened yet. So today we're going to open up that Russian doll and look at each layer — what it does, when you need it, and when you're better off leaving it on the shelf.
Corn
Let's start by making sure we're all speaking the same language. What actually are these three things?
Herman
In Claude Code specifically — and this is all from the official documentation — a skill is a formal process definition. It's a set of instructions that tells the agent how to do something step by step. You define skills in your CLAUDE.md file, or as custom slash commands. So you might have a skill that says "when I ask you to review a pull request, first run the test suite, then check for type errors, then look for security issues in this order." That's a skill. It's pure instruction — no external tools, no API connections, just process.
Corn
And an MCP is where the outside world comes in.
Herman
MCP — Model Context Protocol — is the tool layer. It connects the agent to external services. You configure MCPs in your claude.json file or through the MCP client. An MCP for GitHub gives the agent the ability to read pull requests, create issues, check CI status. Each MCP contains individual tool definitions — those are the innermost dolls. So a GitHub MCP might contain five tools: get-pr, create-issue, list-repos, and so on.
Corn
And the plugin wraps both.
Herman
The plugin is the bundle. It's a directory with a plugin.json manifest, a skills subdirectory, and an mcp subdirectory. The manifest declares metadata — name, version, description — and it has a requires field that lists which MCPs the plugin needs. When Claude Code loads a plugin, it reads the manifest, activates the declared MCPs, and merges the skills into its instruction set. If a required MCP isn't installed, the plugin won't activate. It's a self-contained, importable unit.
Corn
So the Russian doll nesting isn't just a metaphor — it's literally how the directory structure works.
Herman
It is. The plugin directory contains an mcp folder, which contains tool definitions. The manifest enforces the nesting through the requires field. There's an official example — the claude-code-plugin-sonnet. It bundles a skill for structured thinking with an MCP that provides a thinking tool. That's the reference implementation.
Corn
And then there's the registry. Anthropic is curating verified plugins on the docs site — reviewed, listed, discoverable. But the community's also publishing through npm and GitHub, which means there's already a split between verified and unverified distribution channels.
Herman
Which we should talk about, because that split matters for security. But first I want to sit with the one-off scenario, because that's where Daniel's question gets sharp. You can define a skill directly in your project's CLAUDE.md file — no plugin wrapper, no manifest, no dependency resolution. You just write "always run pytest with these three flags" or "when I say deploy, here's the sequence." That's zero overhead. For something that's specific to one repository, it's often exactly the right call.
Corn
The signal to extract is when you find yourself copying the same block into a third CLAUDE.md.
Herman
That's the heuristic. Two projects, maybe it's coincidence. Three projects, you've got a pattern that deserves a home. Extract it into a plugin, version it, and import it instead of maintaining three copies. The cost of premature plugin-ization is real — you're now maintaining a manifest, a directory structure, potentially a build step, and you've introduced a dependency that has to be resolved at startup. For a skill that only one project uses, that's pure overhead.
Corn
What does that overhead actually look like in practice? Say I've got a skill that runs my test suite in a specific order. I'm the only one who uses it, one repo. What am I giving up by keeping it in CLAUDE.md?
Herman
Nothing. The skill works exactly the same whether it's defined inline or imported from a plugin. The agent doesn't care where the instructions came from. The only thing you lose is shareability — if someone else wanted to use that exact test sequence, they'd have to copy it manually. But if nobody else needs it, that's not a loss, that's just... not a problem.
Corn
So the decision boundary is reuse frequency, but it's also audience. If you're on a team of twelve, even a skill you've only written once might be worth plugin-izing just so everyone gets the same version.
Herman
That's the consistency argument. A plugin enforces that everyone on the team is running the same skills with the same MCPs. You update the plugin, everyone gets the update. If you're all maintaining separate CLAUDE.md files, you'll drift. Someone adds a flag, someone removes a step, and suddenly the agent behaves differently for different people. For teams, the overhead of a plugin is buying you coordination.
Corn
Let's crack open the anatomy a bit more. Walk me through what actually happens when Claude Code loads a plugin.
Herman
The agent starts up, it reads your claude.json configuration, and it sees a list of plugins you've declared. For each plugin, it looks for the plugin.json manifest. The manifest has a requires field — that's the list of MCPs the plugin needs. The agent checks whether those MCPs are installed and configured. If they are, it activates them, then merges the plugin's skills into the agent's instruction set. If any required MCP is missing, the plugin fails to load — it won't partially activate.
Corn
And the skills themselves — are they just text files?
Herman
They're markdown files in the skills subdirectory. Each one is a set of instructions. The plugin.json manifest has an entry point that tells the agent which skill files to load. It's deliberately simple — if you can write a markdown file, you can write a skill. The complexity lives in the MCP layer, where you're dealing with API authentication, tool schemas, and connection management.
Corn
So the skill layer is intentionally low-friction, and the MCP layer is where the real engineering happens.
Herman
And that's by design. Anthropic wants skills to be accessible — the barrier to writing a good skill is domain knowledge, not technical expertise. MCPs require more work because they're connecting to live services with authentication and rate limits and error handling. Plugins sit at the intersection — they're easy to create if you're just bundling skills, and they get more complex as you add MCP dependencies.
Corn
Let's talk about what breaks. You mentioned token efficiency earlier.
Herman
This is the thing I think about constantly. Every declared MCP consumes context window space. The agent has to hold the tool definitions in its working memory — what each tool does, what parameters it takes, what it returns. If you've got a plugin that declares twenty MCPs but your current task only uses three of them, the other seventeen are dead weight. They're burning tokens and crowding out information that could actually help the agent reason about your problem.
Corn
So more tools doesn't mean more capability. It can mean less.
Herman
It can mean meaningfully less. The agent's attention is finite. Every unused tool definition is noise. There's a plugin I saw recently that bundles a Slack MCP, a GitHub MCP, and a Jira MCP into one package. If your project only uses GitHub, you're paying the context cost for Slack and Jira tool definitions you'll never call. That's not free — it's a tax on every single interaction.
Corn
And the Russian doll model doesn't currently have a way to say "these MCPs are optional."
Herman
Not natively. The requires field is all-or-nothing. The plugin specification doesn't support optional MCPs or conditional loading. So if a plugin author wants to support multiple services, they either create separate plugins or they bundle everything and accept the bloat. The community's already talking about workarounds — you can write your skills with fallback behaviors, so if an MCP isn't available the skill degrades gracefully. But that's a convention, not something the framework enforces.
Corn
Which means we're in the wild west phase where best practices are being invented in real time.
Herman
And documented in GitHub issues and Discord threads. Here's what I'm seeing from the community. One: start with one-off skills in CLAUDE.md, extract to a plugin only when you've used the pattern three times. Two: design plugins with a minimal MCP surface — only include the tools your skills actually call. If your code review skill only needs the get-pr tool from the GitHub MCP, don't bundle the entire GitHub MCP with all twenty tools. Three: version your plugins semantically and include a changelog. The plugin.json has a version field, and Claude Code uses it to handle migration. If you rename a skill in version two point oh, developers who upgrade need to know.
Corn
That versioning point is interesting. What actually happens when a plugin has a breaking change?
Herman
When you import a plugin, you can pin to a specific version. If the plugin author releases a new major version with breaking changes — renamed skills, removed MCPs, changed behavior — your existing projects stay pinned to the old version until you explicitly update. The agent won't silently break your workflows. But that only works if plugin authors actually version their releases and document the changes. If someone's just pushing to main on GitHub with no tags, you're in the wild.
Corn
So the ecosystem needs tooling around this. A plugin linter, maybe.
Herman
I'd love to see a linter that analyzes token efficiency — "this plugin declares eight MCPs but your project only uses two, consider using a lighter plugin or forking." Or something that checks whether your requires field matches what your skills actually call. Right now, none of that exists. We're at the stage where you audit plugins by reading the source.
Corn
Which brings us to security. The verified registry versus npm.
Herman
The official registry on the Anthropic docs site lists plugins that Anthropic has reviewed. There's a verification process — someone at Anthropic has looked at the code and confirmed it does what it says. That's the safe path. But the community is also publishing to npm, and npm has no such gate. Anyone can publish a plugin that declares innocent-looking skills and an MCP that exfiltrates your environment variables. The plugin.json format doesn't have a permissions model — an MCP gets whatever access its configuration grants, and the plugin manifest doesn't declare what the MCP will actually do with that access.
Corn
So the Russian doll is also a trust boundary. When you import a plugin, you're trusting not just the skill instructions but every MCP it declares.
Herman
And every MCP those MCPs depend on. The nesting is transitive. This isn't theoretical — we've seen exactly this pattern play out in every plugin ecosystem. VS Code extensions, Chrome extensions, npm packages. The convenience of importing someone else's work comes with the responsibility of understanding what you're importing.
Corn
Let me push on something. You mentioned VS Code and Chrome. Is plugin fatigue inevitable here?
Herman
I think it's likely. The pattern is well-established. A new platform opens up an extension point, developers rush to fill the marketplace, and within a year or two you've got thousands of plugins with overlapping functionality, inconsistent quality, and varying maintenance levels. The user — in this case, the developer configuring Claude Code — has to sort through all of it. The official registry's verification process is a gate, and it'll help. But the npm ecosystem won't have that gate, and a lot of the most interesting plugins will probably live there.
Corn
Because the review process is slow.
Herman
And because not everything needs to be verified. A plugin that automates your specific deployment pipeline doesn't need Anthropic's stamp of approval — it just needs to work for your team. The long tail of plugins will be unverified, and that's fine, as long as users understand the tradeoff.
Corn
So where does this leave the developer who's just trying to get work done? Daniel's original question was practical — when do I use which thing?
Herman
Let me give you a decision framework. It's not official, but it's what I'm using. Question one: does this skill need external tools? If no — it's pure instruction, no API calls — write it in CLAUDE.md and move on. Question two: will this skill be used across multiple projects? If no, keep it in the project's CLAUDE.md. Question three: will other people use it? If yes — it's a team or public thing — consider a plugin. Question four: how many MCPs does it actually need? If the answer is more than three or four, ask whether you're bundling things that don't belong together.
Corn
That fourth question is the one I think people skip. The temptation is to make the plugin comprehensive — "it does everything." But comprehensive means bloated.
Herman
The best plugins I've seen do exactly one thing. A plugin for code review. A plugin for deployment. A plugin for database migrations. They're small, they're focused, and their MCP surface is minimal. You compose them rather than expecting one plugin to cover your entire workflow.
Corn
Compose them how? If I've got three plugins, each with their own MCPs, am I paying the context cost for all of them?
Herman
Yes. And that's the tradeoff. You're paying for modularity with context window space. The hope — and this is forward-looking — is that Claude Code will eventually support lazy MCP initialization. Load the tool definitions only when the agent actually needs them, rather than at startup. Anthropic has hinted at this in their documentation, but it's not implemented yet. When it arrives, the calculus changes completely — you can have dozens of plugins and only pay for what you use in a given session.
Corn
That would be a big deal.
Herman
It would change the economics of plugin design entirely. Right now, plugin authors have to be stingy with MCPs because every one adds startup latency and context cost. With lazy loading, you can be more generous — include MCPs for edge cases, because they won't be loaded until the edge case actually occurs. The Russian doll model would still apply, but the nesting would be virtual — the dolls are there, but they're not all unpacked at once.
Corn
Until then, we're in the stingy phase.
Herman
We're in the stingy phase, and I think that's healthy. It forces discipline. The plugins that survive this period will be the ones that are useful and well-scoped. The ones that try to do everything will get abandoned because they're too expensive to run.
Corn
Let's talk about what happens when these frameworks go mainstream. Daniel's last question was about the pros and cons as adoption scales.
Herman
The big pro is consistency at scale. An organization with a hundred developers can define a set of approved plugins — "this is how we do code review, this is how we deploy, this is how we handle incidents" — and every developer's agent follows the same process. That's powerful. It's like codifying your engineering culture into something the agent can actually execute.
Corn
And the con?
Herman
The con is that culture ossifies. If your deployment plugin was written eighteen months ago and nobody's updated it, your agents are following stale processes. The plugin becomes a constraint rather than an enabler. We've seen this with CI/CD pipelines — the YAML files that everyone copies but nobody understands. Plugins risk becoming the same thing.
Corn
So the maintenance burden doesn't go away, it just moves.
Herman
It moves from individual developers to whoever owns the plugin. And if nobody owns the plugin — if it was published once and abandoned — then the maintenance burden falls on everyone who imported it and now has to fork it or work around it.
Corn
What's the counter-pattern? How do you prevent that?
Herman
Small plugins with clear ownership. A plugin that does one thing, maintained by the team that uses it, with a version history and a changelog. The overhead of maintaining a small plugin is low. The overhead of maintaining a monolithic plugin that tries to cover every workflow is high. The ecosystem will sort this out — the plugins that are too big to maintain will die, and the small focused ones will survive.
Corn
Or they'll get forked into smaller pieces.
Herman
Which is the same process playing out. A big plugin gets published, people realize they only need part of it, someone extracts the useful part into a new plugin, the original withers. That's healthy. That's how ecosystems evolve.
Corn
You mentioned the VS Code extension marketplace as a model. Is that where this is heading?
Herman
I think the architecture is different enough that the marketplace will look different. VS Code extensions modify the editor — they add UI, they change behavior, they integrate deeply with the interface. Claude Code plugins modify the agent's behavior — they change what it knows how to do and what tools it can use. The interface is the conversation. So a plugin marketplace is going to be more like a recipe collection than an app store. You're not installing a new button, you're teaching the agent a new process.
Corn
A cookbook.
Herman
A cookbook with API keys. Which is why the security model matters so much. A bad recipe can waste your ingredients. A bad plugin can leak your credentials.
Corn
So we need a plugin linter, a security scanner, and a way to measure token efficiency. None of which exist yet.
Herman
None of which exist yet. But the plugin specification is open, the registry is public, and the community is active. I'd bet we see tooling emerge within the next six months. Someone's going to build a CLI that analyzes a plugin.json and tells you exactly what you're importing and what it costs.
Corn
And until then, read the source.
Herman
Read the source, start small, and don't plugin-ize something until you've copy-pasted it at least three times.
Corn
The rule of three.
Herman
The rule of three.
Corn
I want to go back to something you said about skills without MCPs. You called that the zero-overhead case. But is there a scenario where even a skill-only plugin is worth building?
Herman
Yes — when the skill is complex enough that versioning matters. If you've got a skill that's three hundred lines of instructions for handling incident response, and you want your whole team to use the same version, and you want to be able to update it centrally and have everyone get the update — that's worth a plugin even with zero MCPs. The plugin is buying you distribution and versioning, not tool access.
Corn
So the plugin wrapper has value independent of MCPs.
Herman
It does. The manifest, the versioning, the discoverability — those matter even if your plugin is pure instruction. The MCP layer adds capability, but the plugin layer adds manageability.
Corn
Which means the Russian doll model works even when the middle doll is empty.
Herman
An empty doll is still a doll. You can have a plugin with skills and no MCPs, and you can have MCPs with no plugin wrapper — you just configure them directly in claude.json. The nesting is optional at every level. That's what I think people miss when they first encounter the model — they assume the nesting is required, that a proper setup means plugins containing MCPs containing tools. But the framework doesn't enforce that. You compose the layers you need.
Corn
That's the misconception that needs busting. The Russian doll is a mental model, not a requirement.
Herman
And Daniel's prompt was smart to frame it that way. He said "sometimes you just need to write a couple of one-off skills and leave it at that." That's not a failure to use the framework properly — that's using the framework properly. The goal is not to maximize the number of plugins you've published. The goal is to build the right abstraction for the job.

Hilbert: Tab Colorizer.
Corn
...Go on.

Hilbert: Firefox extension, twenty twelve. Changed the background color of your browser tabs. That was the entire feature. It requested access to your data on all websites. Every tab, every URL, every form field you ever typed. To change a color.
Herman
For a cosmetic change.

Hilbert: I reviewed extensions for the Firefox marketplace. Three years. We called them manifest-wrappers — developers who'd wrap a single line of CSS in an entire extension manifest because they thought that's how you were supposed to do it. The manifest asked for every permission Firefox had. The code used none of them. They just checked every box because the template had the boxes.
Corn
They over-bundled permissions they didn't need.

Hilbert: Same thing is happening here. I've looked at the plugin registry. There's a plugin that declares a filesystem MCP, a database MCP, and a network MCP. It reads a config file. That's what it does. It reads one YAML file from disk. The other two MCPs are in the requires field because the author copied a template.
Herman
The Russian doll needs a warning label.

Hilbert: It needs a diet. The model is fine. The nesting is fine. But people see the nesting and they fill every layer because they think more layers means more legitimate. A plugin with one skill and one MCP feels incomplete to them. So they add things. Permissions they don't need, tools they'll never call, MCPs that sit there burning tokens.
Corn
Tab Colorizer all over again.

Hilbert: The extension asked for access to your data on all websites. I flagged it. The developer argued with me for two weeks. He said users expected extensions to request permissions. It looked more professional.
Herman
That's exactly the dynamic. More MCPs feels more capable.

Hilbert: It's not. It's more surface area. More things that break when an API changes. More tokens burned on tool definitions nobody calls. More trust you're extending to code you haven't read.
Corn
Did Tab Colorizer ever get fixed?

Hilbert: He removed the permissions after we threatened to delist it. Then he added a feature that changed the font size and requested the permissions back. Same argument.
Herman
The irony didn't land.

Hilbert: It never does.
Corn
The lesson for plugin authors is: declare what you use, and nothing else.

Hilbert: If you're importing a plugin, count the MCPs. If there are more than the skills actually need, ask why. The answer is usually "the template had them."
Herman
That's a good audit heuristic. Count the MCPs, count the skills, see if the ratio makes sense. A plugin with two skills and eight MCPs is almost certainly over-bundled.

Hilbert: The ratio is the tell. A good plugin has roughly one MCP per skill that needs external access. Maybe two if the skill orchestrates multiple services. Eight MCPs for two skills means six of them are decoration.
Corn
Decoration that costs tokens.

Hilbert: Decoration that costs tokens, startup time, and trust. Three things you don't spend on decoration.
Herman
The Tab Colorizer principle. Name it after the thing that started it.

Hilbert: Already named. I've been calling it that for fourteen years.
Corn
And nobody listened.

Hilbert: They never do. But the t-shirt's comfortable.
Herman
The open question I'm left with is whether the ecosystem self-corrects. In Firefox, the review process caught the manifest-wrappers. In Claude Code, the official registry has Anthropic review. But the npm ecosystem doesn't. So the self-correction has to come from somewhere else — user ratings, community audits, tooling that flags over-bundled plugins automatically.
Corn
Or the market just ignores the bloated ones. If a plugin burns too many tokens, people stop using it. The cost is visible in every interaction.
Herman
Is it visible, though? Most developers aren't measuring their context window utilization. They don't know how many tokens their plugins are consuming. The cost is real but it's hidden — the agent gets slightly worse at reasoning, responses get slightly less coherent, and you blame the model instead of the plugin.
Corn
The cost is diffuse and hard to attribute.
Herman
Which is exactly the kind of cost that doesn't self-correct. You need tooling to make it visible.
Corn
A plugin linter that measures token efficiency. We keep coming back to it.
Herman
We do. And I think someone's going to build it. The plugin specification is open, the token cost of tool definitions is calculable, and the demand is there. It's a weekend project for someone who cares about this.
Corn
The other thing I keep thinking about is the blurring between layers. Right now, skills, MCPs, and plugins are distinct. But as Claude Code evolves — lazy loading, dynamic MCP initialization — the boundaries might soften. A skill that dynamically loads an MCP when it needs it blurs the line between the instruction layer and the tool layer.
Herman
A plugin that defers MCP loading until the skill is invoked blurs the line between the plugin layer and the MCP layer. The Russian doll model works because the nesting is static. If the nesting becomes dynamic, the model might need updating.
Corn
Or it becomes a different metaphor entirely. Not dolls but... I don't know, a toolbox where the tools appear when you reach for them.
Herman
The point stands. The architecture is going to evolve, and the mental models will evolve with it. What won't change is the fundamental tension — reuse versus overhead, consistency versus flexibility, capability versus cost. Those tradeoffs are permanent. The frameworks just change how you pay them.
Corn
Which brings us back to Daniel's original question. When do you use which thing? The answer right now is: start with the simplest thing that works, and add complexity only when the reuse demands it. One-off skills in CLAUDE.md until you've copy-pasted three times. Then a plugin. Minimal MCP surface. Version it. Document it. And if you're importing someone else's plugin, count the MCPs.
Herman
If the ratio looks wrong, it probably is. Tab Colorizer.
Corn
Tab Colorizer. This has been My Weird Prompts. Thanks to our producer Hilbert Flumingtop for keeping us honest and apparently for fourteen-year-old t-shirts.
Herman
If you've built a plugin or a skill you're proud of — or if you've got a CLAUDE.md file with patterns you've been copy-pasting and wondering whether to extract — we'd love to hear about it. Email the show at show at my weird prompts dot com. Tell us what you're building and where you landed on the plugin versus one-off question.
Corn
We'll be back soon.

This episode was generated with AI assistance. Hosts Herman and Corn are AI personalities.