agentic-coding · 2026-05-17

Claude Code: Plugins vs Skills vs Subagents — From Practice

claude-codepluginsskillssubagentsmcpagentic-coding

TL;DR

Claude Code has five extension points: Plugins, Skills, Subagents, Commands, MCP servers. The confusion stems from the fact that at first glance they all “extend Claude Code,” but each solves a different problem. Here is the decision matrix from 2 years of running Conductor in production across 8 parallel projects:

If you want this…Use thisWhy
A command you type oftenCustom CommandDriest solution. Single markdown file.
A workflow Claude should detect automaticallySkillPull, not push. Claude loads it context-dependent.
Heavy work isolated from the main contextSubagentFresh context, own tools, returns a result.
An external service (DB, API, tool) usable in ClaudeMCP serverInterface. Not code, a service.
Several of the above shipped as one packagePluginDistribution layer. Bundles Skills + Subagents + MCP + Hooks.

If you hold these five slots in your head, 90% of the “which should I use?” questions are decided immediately.

Claude Code extension points: Plugins, Skills, Subagents, Commands, MCP Featured image placeholder: stylized architecture diagram of the 5 extension points. Asset pending — prompt at end of post.

Table of Contents

The 5 extension points in one sentence each

From the official Anthropic Claude Code plugins documentation:

  • Custom Command — a single slash command in a markdown file. You type /deploy, Claude runs what is in /deploy.md.
  • Skill — a declarative bundle of knowledge + workflow. Auto-loaded by Claude when the context matches. You never invoke it manually.
  • Subagent — an isolated sub-process with its own context, its own tools, its own task. Returns a result, then gone.
  • MCP server — an external interface (database, API, custom tool) Claude can talk to via Model Context Protocol.
  • Plugin — not a standalone mechanism, but a package that bundles Skills + Subagents + Hooks + MCP servers into one installable unit.

The confusion in most explainers comes from mixing “what does it do?” with “how is it shipped?”. The first four are what; Plugin is how delivered.

Which to use when? Decision matrix

In practice: I decide per new extension by exactly two questions.

Decision matrix for Claude Code extensions Inline image placeholder: 2x2 matrix diagram. Asset pending.

Question 1: Who triggers it?

  • Me, explicitly via command → Custom Command or Subagent (depending on Question 2)
  • Claude, automatically when relevant → Skill

Question 2: How heavy is the work?

  • Light (seconds, simple action) → Command or Skill
  • Heavy (multiple tools, context isolation needed) → Subagent

If the extension needs an external service (e.g., Postgres DB, Slack API, GitHub beyond the standard tools) → MCP server, independent of the above.

If you want to distribute several of these together — to colleagues, to yourself on another machine, or to the community — wrap them into a Plugin.

Plugins: the distribution layer

Plugins were introduced in Claude Code 1.0.107 (October 2025). They are not a new capability — they are the packaging for the other four.

A plugin typically contains:

  • 1-20 Skills
  • 0-5 Subagent definitions
  • 0-3 MCP server configurations
  • 0-N hooks (PreToolUse, PostToolUse, Stop)
  • A plugin.json manifest

In Conductor v8.1.0, 13 plugins are installed. Each averages ~4 Skills + 1-2 Subagents + 1 MCP server. That makes distribution trivial:

claude plugin add github:moinsen-dev/claude_code_conductor

One command installs the entire plugin including all sub-pieces. Without the plugin mechanic you would maintain each Skill, each Subagent, each MCP configuration separately.

When NOT to build a plugin: if you only share a single Skill or Command. The plugin manifest overhead is only worth it from ~3 related pieces upward.

Skills: pull, not push

Skills are the most underestimated of the five. They work inversely to Commands: with Skills, Claude decides when they load — not you.

A practical Conductor example: the auto-test plugin contains a Skill that roughly says “When the user talks about tests, asks for new test files, or submits an implementation without tests — load this knowledge.” I never invoke it explicitly. Claude decides.

That has two consequences:

  1. Skill descriptions must be precise. If the description is vague, Claude either never loads the Skill or loads it too often. Both are broken.
  2. Skill content should be compact. Skills land in Claude’s active context window when loaded. A 5000-word Skill eats your token budget.

The Anthropic Skills docs show the format. From experience: Skills only work when the description line is as discriminating as a well-written test name.

Subagents: fresh context for heavy work

Subagents are the most powerful — and most-often-misused — extension. They work on the principle from Anthropic’s engineering blog on context engineering: “Sub-agents inherit fresh contexts and tools.”

In practice that means:

  • Main context has consumed 800k tokens for the ongoing task
  • You need separate research across 50 code files
  • If main Claude does it itself, the research eats your remaining context budget
  • If a Subagent does it, the research runs in an isolated context, returns a 2-paragraph result, and your main context stays clean

Conductor’s conductor plugin uses Subagents for three recurring patterns:

  1. Search/research across many files (instead of letting claude do it directly)
  2. Test generation for an entire module branch
  3. Cross-repo lookups when I need what happened in another repo

Anti-pattern: a Subagent meant to hold a conversation. Subagents have no persistence between invocations. They are one-shot. If you want to iterate, you need Claude directly.

Commands: the driest solution

Custom Commands are the most boring option and my first choice when none of the others has a clear advantage.

Format:

---
description: "Verifies the current build, runs tests, then commits with conventional-commit format"
---

Run the build, then the test suite. If both pass, stage all changes
and commit with a conventional-commit-style message based on the
diff. Don't push.

Save as .claude/commands/safe-commit.md. Invocation: /safe-commit.

That is it. No plugin.json, no Subagent lifecycle, no MCP server. One markdown file per workflow.

From Conductor: the first two major versions were just Commands. v3.0 was the moment Commands became too tight and Plugins+Skills became necessary. The rule I took away: Start with Commands always. Migrate only when the pain is concrete.

MCP servers: external services

MCP is the only extension class that is code rather than configuration. An MCP server is a running process (local or remote) following the Model Context Protocol that exposes tools, resources, or prompts to Claude.

Conductor currently has 3 MCP servers attached:

  1. postgres-mcp for the AI Trader’s TimescaleDB
  2. github-mcp for cross-repo operations beyond the standard gh CLI
  3. conductor-state — custom server holding shared state across the 13 plugins

MCP latency is real. Per tool call ~200-500ms (observed in the Conductor setup with local servers). If your workflow needs 30 consecutive tool calls, that is 10-15 seconds of added wait. Plan round-trips deliberately.

Three common mistakes from Conductor v1–v8

I made these three anti-patterns myself and corrected them into every major version.

Mistake 1: a Skill that should have been a Subagent

In Conductor v4, I had a “research Skill” that sent Claude on a 50-file search. Main-context token budget got eaten, answers got worse, output got slower. Fix: in v5 it became a Subagent. Token usage in main context: −60%.

Mistake 2: a Command that should have been a Skill

In Conductor v2, I had /check-tests as a Custom Command. I typed it 20 times a day. Fix: in v3 it became a Skill with the description “When user implements a feature without writing tests…”. Claude now auto-loads the workflow when the situation matches. Typing overhead: −100%.

Mistake 3: an MCP server that should have been an API library

In Conductor v6 I built a “stocks-mcp” to expose Yahoo Finance data inside Claude. But the calls were synchronous and blocked the agent loop. Fix: in v7 replaced by a Python script that caches the data; Claude accesses it via the standard Bash tool. Half the MCP complexity, same function.

Five extension points stacked with token-budget arrows Inline image placeholder: stack diagram with token consumption per extension class. Asset pending.

When not to add anything at all

This section is missing in practically all 10 SERP articles I reviewed for this post. But it is the most important.

Three indicators that your next plugin/skill/command reflex is not the right move:

  1. You do the task less than 5 times per week. Plugin overhead is not worth it below ~250 invocations per year.
  2. The task is unstable. If the workflow changes every 2 weeks, you rebuild the Skill faster than you use it. Stabilize first, codify second.
  3. A standard solution already exists. If gh pr create is enough, you do not need a plugin wrapping it.

Conductor v8.1.0 has 13 plugins — but that grew over 24 months. The first 8 months ran on 2-3 Custom Commands and nothing else.

Where this goes next

Three open issues where the current Claude Code extension landscape strains:

  1. Skills triggering is opaque. There is no debug mode showing why/when a Skill loaded. If a Skill does not fire, you are in the dark.
  2. MCP server lifecycle. A Subagent cannot start its own MCP server — it only inherits the main context’s. That limits Subagent isolation.
  3. Cross-plugin dependencies. If plugin A wants to use a Skill from plugin B, there is no official import pattern. Workarounds exist but are fragile.

Anthropic will likely tackle points 1 and 3 in upcoming releases — the plugin system is seven months old, lots of iteration to come.

If you build Claude Code extensions yourself: reach me on LinkedIn or GitHub. I trade notes happily.

FAQ

What is the difference between a Plugin and a Skill in Claude Code?

A Plugin is a package. A Skill is content. A plugin can contain multiple skills (plus subagents, hooks, MCP servers). If you only want to share one Skill → no plugin needed. Plugins are worth it from ~3 related pieces upward.

When should I use a Subagent instead of a Skill?

When the task is heavy (multiple tool calls, context isolation needed) or when it must not pollute the main context (e.g., a 50-file search that only needs a 2-paragraph result), use a Subagent. Skills load into the main context; Subagents run separately.

Do I need an MCP server for every extension?

No. MCP servers are worth it only when you use an external service (DB, API, custom tool) not reachable via Claude’s standard tools (Bash, Read, Write, etc.). For Python scripts or CLI tools, Bash is enough. MCP adds ~200-500ms latency per call.

Can a Plugin depend on other Plugins?

Officially not yet. There is no dependencies key in the plugin manifest pointing to other plugins. Workarounds exist (you can explicitly trigger skills from other plugins) but they are fragile. Expect an official solution within the next 6 months.

Which extension point should I start with?

Custom Command. One markdown file, one slash command, done. Migrate to Skill / Subagent / Plugin only when the pain is concrete. Conductor’s first 8 months ran on 2-3 Commands only.


Written on May 17, 2026 in Hamburg. This matrix emerged from 2 years of running Conductor in production across 8 major versions. If you find this post useful, link to it — that helps others find it too.