Skip to content
Back to all field notesruntimeUpdated · 11 min

Agent skills vs MCP servers vs rules files: what each one costs

Every comparison of these three argues about what they are. The question that decides which one you reach for is when each gets loaded, and what it takes out of your window on the turns you never use it.

field note11 min

You want your agent to stop writing migrations the wrong way. There are three places you could put that, and no obvious reason to pick one. You can write it into AGENTS.md. You can package it as a skill. You can stand up an MCP server that exposes a migration tool. Every guide I have read on this answers a different question than the one I have, which is not what are these things but what does each one cost me on the four hundred turns where it never gets used.

That cost is real and it is invisible. A capability you deliver the wrong way does not error. It sits in the window, quietly taking room from the task, and you find out later when the agent starts skimming the thing you most needed it to read.

The three channels, quickly

I am not going to re-derive what belongs in a rules file. That argument already has a home in where your decisions should actually live, and the short version is that rules files carry operational facts about the repo, not product decisions. The companion question, how to write those operational lines so an agent follows them, covers the length ceiling that makes this routing decision matter in the first place.

A rules file (AGENTS.md, the open standard defined at agents.md, or a vendor file like CLAUDE.md) is text the harness reads and puts in front of the agent. It is always there. That is the whole point of it and also the whole problem with it.

A skill is a folder with a description and a body. The harness shows the agent the descriptions of everything available, and pulls in the body only when a task looks like a match. Anthropic describes the general pattern in their writing on context engineering, where agents keep lightweight identifiers around and fetch the real content when they need it rather than pre-loading everything up front.

An MCP server is a running process the agent talks to over a protocol. It is not text at all, it is a live connection with real tools behind it, which is why it can hold credentials, hit a database, or return something that was true one second ago. The current spec made the protocol stateless at its core and added a server/discover method so clients can fetch server capabilities when they want them up front.

The split is not only mine. When GitHub made both generally available in Copilot code review, it drew the same line: skills carry your team’s internal tools and coding standards as SKILL.md files in the repo, while MCP connections pull context from third-party platforms like issue trackers and service catalogs.

Three different mechanisms. The interesting part is not the taxonomy, it is what happens to each one on a turn where the task has nothing to do with it.

When it loads is the whole question

Connect a handful of MCP servers and look at what your agent is carrying before you have typed a task. Every tool from every connected server, each with a name, a description and a schema, described well enough for the model to choose between them. That inventory goes with the request. It is there on the turn you use the database tool and it is there on the four hundred turns you do not.

The same is true of a rules file, and that part is already documented in this cluster: every line the harness auto-loads is spent on every call. What I want to add is that the rule generalizes. Anything the harness wires in permanently is paid for permanently, and MCP servers are the most expensive version of it because the tool list grows with every server you connect and nobody prunes it. Context is a finite resource whatever you spend it on, and this is a bill you agreed to without reading.

A skill is the only one of the three with a cheap idle state. The agent carries the description and nothing else until a task matches. You can have a hundred skills installed and pay almost nothing for the ninety-nine that are irrelevant right now.

ChannelWhen it loadsCost on an unrelated turnHow it fails
Rules filealways, every callthe whole filegoes stale and misleads
MCP serverconnected all sessionevery tool descriptioncrowds out the task, or the process dies
Skillon demand, when matchedthe description onlynever gets picked
Subagentspawned mid-task by the parentnothing, until spawned, then its own separate windowdrifts from the parent, or costs more in coordination than the isolation buys
Plugininstalled once from a catalogwhatever the skill, MCP server or command it bundles already coststhe catalog serves a stale or untrusted version

That last column is the one people skip, and it is where the choice actually bites.

Each one fails in its own way

A rules file fails by aging. It keeps saying something that stopped being true, nothing throws, and the agent follows it with total confidence. That failure mode has its own piece in your rules file is lying to your agents, so I will leave it there.

A skill fails at the door. The agent never sees the body, so the failure is invisible from inside the skill: the content is perfect and it simply did not get picked. The description is the load-bearing part, and it is the part everyone writes last, in a hurry, after the interesting work is done. If your skill is called helpers and described as “utilities for the project”, it will lose every match to a task that needed it. When a skill seems not to work, the body is rarely the problem.

An MCP server fails in two directions at once. It can fail loudly, which is the good case, because a dead process or an auth error is something you can see. The bad case is quiet. Connect enough servers and the agent starts choosing badly between forty near-identical tools, or the tool inventory eats the room the actual task needed. A server with one sharp tool is worth more than a server with thirty, and this is the opposite of how most of them ship.

paid every turn

  • rules file text
  • every tool schema
  • idle costs full price

paid when used

  • skill description
  • body on match
  • idle costs almost nothing
The split that decides the choice: permanent wiring bills you on every call, while on-demand loading only bills you on the turns that need it.

Subagents and plugins are a different axis

Two more names get thrown into this comparison lately, and neither is a fourth way of loading text into the window. A subagent is an isolation mechanism: the parent spawns it, and as of Claude Code 2.1.232 a fork inherits the full parent conversation and prompt cache instead of starting cold, with non-teammate spawns now running in the background by default. The cost is not idle context, a subagent that never gets spawned costs nothing, it is coordination: someone has to decide what goes into the fork, wait for it to come back, and reconcile what it found with the parent’s task. Reach for one when a piece of work benefits from a window of its own, a parallel investigation that would otherwise fill the parent’s context with search results it does not need to keep, not as a way to avoid writing a skill.

A plugin is a distribution mechanism, not a delivery channel of its own. Agent Plugins reaching general availability across VS Code, Copilot CLI, the Copilot SDK and the Copilot app, and Codex’s portable plugins that install across local, personal, workspace and remote catalogs, both package the same three things this piece already covers, skills, MCP servers, commands, into one installable unit. Its cost profile is whatever the thing inside it costs: a plugin that bundles a skill behaves like a skill, a plugin that bundles an MCP server behaves like an MCP server. What a plugin adds on top is catalog risk, you are trusting whoever maintains that catalog to ship the version they say they are shipping, and a workspace or remote catalog can drift out from under a team without anyone noticing.

Neither changes the answer to the original question. If the capability is a procedure, it is a skill, whether or not you distribute that skill through a plugin. If it needs live reach, it is an MCP server, plugin or not. What subagents and plugins change is orthogonal: how isolated the work runs, and how it gets installed.

What I actually run

The split I have settled on, operating agents across more than one engine:

  • Operational facts that are true every turn go in the rules file. How to build, how to run tests, what not to touch. Short enough that it stays read rather than skimmed.
  • Procedures that apply sometimes go in skills. How we do a migration, how we cut a release, the review checklist for anything touching money. These are the ones that would bloat a rules file into uselessness, and they are exactly what on-demand loading was built for.
  • Anything needing live state, credentials or a real system goes to MCP. That is the only one of the three that can actually reach your database, and it is worth the permanent cost when you genuinely need reach. I connect few servers and I disconnect the ones a project does not use.
  • Product decisions go in none of them. They belong in an artifact that carries its reason and can be checked, which is the argument in the rules-files piece and the reason durable memory lives outside the session.

The failure I see most often is a team reaching for MCP because it sounds like the serious option, when what they had was a procedure. A procedure is a skill. Standing up a server for it buys a permanent context bill and an extra process that can be down, in exchange for text you could have loaded on demand.

None of this makes the agent’s output trustworthy on its own. Delivering a capability well means the agent is more likely to have the right instructions in front of it, which is upstream of whether the work was done correctly. That still gets settled by evidence at the gate, not by how neatly you packaged the instructions.

Where PaellaDoc fits

Every one of these three is a way of getting text or reach in front of an agent at the right moment, and none of them is a place to keep what your product decided. That is the thread running through everything I build. The channel question is a harness question, part of the harness being the thing worth engineering, and it is the kind of decision you currently make by hand and re-make every time you add a tool. PaellaDoc keeps the decisions, the criteria and the reasons as artifacts that travel with the task and get checked whatever engine runs it, so the channel you pick is a delivery detail rather than the place your product memory happens to be stored. Holding all of that together by hand is what you are the runtime is about.

FAQ

Should I use a skill or an MCP server?

If the capability is knowledge or procedure, text that tells the agent how to do something, use a skill and pay for it only when it matches. If it needs live data, credentials or a connection to a real system, use MCP, because a skill cannot reach anything on its own. The test is whether you are teaching the agent something or giving it reach.

Does connecting more MCP servers slow my agent down?

It costs you context on every turn, because the tool inventory travels with each request whether you use those tools or not. It also makes tool selection harder, since the model has more near-identical options to choose between. Connect the servers a project actually needs and drop the rest.

Why does my skill never trigger?

Almost always the description, not the body. The agent decides whether to load a skill from its name and description alone, so a vague description loses the match before the content is ever seen. Write the description as the situation it applies to, in the words a task would use.

Should I use a subagent or a plugin instead of a skill?

They answer different questions. A subagent buys isolation, a separate context window for a piece of work that would otherwise crowd the parent’s, and it costs coordination, not idle context. A plugin buys distribution, an install path across catalogs for a skill, MCP server or command you already built, and it costs whatever that packaged thing already costs plus the risk of trusting the catalog. Neither is a fourth loading behavior alongside the three above, they change how isolated the work runs and how it gets installed, not what it costs to carry when idle.