Skills, Tools, MCP, Agents: How I Think About the Pieces
I had a few conversations with a friend today, and I ended up laying out how I currently think about agents. Writing it down here so the model in my head stops being a model in my head.
The vocabulary around this stuff — tool, MCP, skill, agent — gets used loosely, and the looseness hides some real distinctions. Here's the taxonomy I've settled on, followed by the parts I find more interesting: how you scale past a single agent, and the two engineering disciplines (context and harness) that decide whether any of it works. The punchline I keep coming back to is in the scaling section: once subagents can talk to each other directly, the coordinating agent stops being the bottleneck, and you can plausibly run harder problems on cheaper, faster models.
Skill vs Tool vs MCP vs Agent
A tool is a function call. Clear, defined input and output. A tool can be implemented with an agent, and it can produce non-deterministic output for the same input and context — but generally a tool is the least dynamic of these things, designed for a specific, concrete task. An AddComment tool posts a comment to a PR during code review. The task is concrete and unit-sized. Anthropic's tool-writing guide puts the non-determinism precisely: a tool is "a new kind of software which reflects a contract between deterministic systems and non-deterministic agents" (Writing tools for agents, Anthropic). The same piece is a good corrective to a habit I have of wanting more tools: "More tools don’t always lead to better outcomes." The well-built ones consolidate — a single schedule_event that finds availability and books, instead of separate list_users, list_events, and create_event calls.
MCP is essentially RPC. It can be backed by a collection of tools, or by agents. That's most of what there is to say at this level of abstraction — but "RPC" only captures the transport. The part MCP actually adds on top is standardized tool discovery and a contract layer: in an MCP server, "tool annotations" can "help disclose which tools require open-world access or make destructive changes" (Writing tools for agents, Anthropic). Calling it RPC flattens that away, and the annotation/safety layer is the interesting bit.
A skill defines hints and suggestions for performing a task. Unlike a tool or an MCP, skills are aimed at more complicated work. A CodeReview skill defines guidelines, best practices, and anti-patterns so an agent knows how to perform a review. It can reference separate guides for different languages and use scripts to figure out which language a PR involves — and the reason it references sub-guides instead of inlining everything is context economy. LangChain calls skills a harness-level primitive that solves the too-many-tools problem via "progressive disclosure" — loading front-matter into context only when needed (Anatomy of an agent harness, LangChain). But a skill can't complete anything on its own — it needs an agent to think and execute. It gives the agent knowledge; it doesn't do the solving. Matt Pocock's skill library is the concrete version: small, composable encodings of engineering discipline (a red-green-refactor tdd skill, a diagnosing-bugs loop), some user-invoked, some reached for automatically by the model (mattpocock/skills).
An agent is the entity that puts things together, and the key is planning. An agent knows which skills, tools, and MCPs it can access. During planning, it breaks a request into smaller tasks and figures out which primitive helps with each. The canonical name for this is Anthropic's orchestrator-workers pattern, where "a central LLM dynamically breaks down tasks, delegates them to worker LLMs, and synthesizes their results" (Building effective agents, Anthropic). That's the planning agent.
Subagents vs Agent Teams
Once an agent can plan its way through a complicated request by decomposing it, the context window becomes the bottleneck. As it invokes skills, tools, and MCPs at each step, its context fills with call details, results, and decisions. You can compact, but over a long job the context window imposes a natural ceiling on the complexity and duration a single agent can handle. And you can't just buy your way out with a bigger window — Google's framework team makes the point bluntly: "simply giving agents more space to paste text can not be the single scaling strategy" (Architecting a multi-agent framework, Google).
Subagents resolve this by spawning fresh agents with clean context. Each is created with only the context it needs for its task. During a code review, one subagent assesses security while another focuses on test coverage. Each handles a smaller task and finishes quickly. Parallelism is nice, but the bigger win is that the main agent no longer holds the execution process of every task in its head — it plans, then collects results. Anthropic describes exactly this shape: "specialized sub-agents can handle focused tasks with clean context windows", each one exploring extensively but returning "only a condensed, distilled summary of its work (often 1,000-2,000 tokens)" (Effective context engineering, Anthropic). That distillation is what saves the main agent's context so it can take on more.
The difference between subagents and an agent team is the communication model.
- With subagents, each one talks only to the main agent. The main agent is the coordinator and relays messages between subagents when needed — though "relay" isn't quite right, because each subagent doesn't actually know the others exist.
- In an agent team, the subagents are aware of each other and can communicate directly.
It's a star topology versus an N-to-N mesh. (That framing is mine — I haven't seen a source put it in exactly those terms, so take it as a model, not a citation.)
That difference shapes how ambiguous and complex a project the system can take on. In the subagent model, the main agent processes every subagent's result. If a security-review subagent reports an issue, the main agent must pass it to an IC subagent; when the fix is done, the main agent must tell the security subagent to validate. Every one of those messages leaves a trace in the main agent's context.
Worse, the main agent is the brain and the coordinator — it has to know that a security-subagent issue implies an IC-subagent fix. All the interaction and workflow logic has to live in its context and stay there, so it doesn't drift or forget. This is the context-explosion failure mode Google describes: if a root agent keeps passing full history down, the "token count skyrockets, and sub-agents get confused by irrelevant conversational history" (Architecting a multi-agent framework, Google).
An agent team solves this by letting the security-review subagent report the issue directly to the IC agent. The main agent never needs to be aware of the internal process of code review — it delegates a complicated, ambiguous task to a team and waits for results. With subagents, it has to crack the whole project into granular enough units to avoid excessive back-and-forth.
So with a team the main agent is less of a bottleneck, both in context-window management and in the raw intelligence it needs for planning. That's the payoff I find most interesting: it becomes plausible to tackle harder problems with less powerful, faster models. Anthropic's managed-agents work points the same direction from a different angle — decoupling the "brain" (the model plus harness) from the "hands" (sandboxes and tools) so that each component "could fail or be replaced independently", and provisioning a brain's hands only when needed dropped their p50 time-to-first-token by "roughly 60%" (Scaling managed agents, Anthropic). Take the coordinator off the critical path and the per-brain load drops; cheaper brains start to suffice.
Context Engineering
Worth dwelling on the context management here. It might be technically feasible to ask the main agent to "forget" a message once it's been relayed — once the security issue has been passed to the IC agent, immediately drop the details so the context doesn't bloat or get polluted. But this is tricky. The definition of "details of the issue" is ambiguous, and the LLM might get it wrong, or at least not be 100% right. Those small errors accumulate into misleading context. It's like compacting: the model might shave off ~50%, but it still has to remember a decent amount — the decisions it's made, the progress so far. Anthropic names the underlying risk exactly: "irreversible decisions to selectively retain or discard context can lead to failures". As they put it, "It is difficult to know which tokens the future turns will need" (Scaling managed agents, Anthropic).
This is why file-based memory is becoming the go-to solution. Files are persistent by design — they're on disk — and combined with git they give you both history and current state. When an agent moves to the next step, it can clear its context and still continue correctly by loading the artifacts from the previous step: a PRD.md, a SYSTEM_DESIGN.md. Anthropic's long-running-agent harness leans on exactly this — a claude-progress.txt log plus git commits let a fresh-context agent get up to speed and resume, precisely because "compaction isn’t sufficient" on its own across many context windows (Effective harnesses, Anthropic). Those artifacts can be reviewed by a human, too, which makes an agent's context far more controllable.
The other half of context engineering is access. What can an agent reach — not just files, but skills, agents, tools, MCPs? Prompt engineering can state the boundaries, but the agent can still forget or misunderstand them. Sandboxing is the alternative: physically limit access. A lightweight virtual filesystem that can be created and destroyed quickly makes an agent much more controllable, and this is a real thing infra teams are building, not a hypothetical. Mintlify's ChromaFs is the clean example — rather than spin up a sandbox and clone a repo, they gave the agent the illusion of a filesystem backed by their existing database, cutting session creation from ~46 seconds to ~100 milliseconds, with per-user access control built in (How we built a virtual filesystem, Mintlify). The same logic extends to skills, agents, tools, and MCPs: control them with a config file. Essentially everything gets defined and bounded by files and a filesystem.
Sandboxing isn't free, though. Anthropic notes that "Sandboxing is safe but high-maintenance", since "each new capability needs configuring, and anything requiring network or host access breaks isolation" — which is why their Claude Code auto mode pairs sandboxing with model-based classifiers rather than relying on physical boundaries alone (Claude Code auto mode, Anthropic). So just sandbox it buys control at a maintenance cost.
Net of all that, context engineering reduces to two operations: define a subagent's boundary, then create the subagent inside that bounded system. Rather than spawning a subagent that shares its own filesystem, the main agent could use a dedicated tool, skill, or agent to streamline the whole define a sandbox → create it → put the subagent in it → destroy it workflow.
Harness Engineering
Here I should be careful, because my mental model is narrower than how the term is usually used. The consensus framing is broad: a harness is "every piece of code, configuration, and execution logic that isn't the model itself" — state, tool execution, filesystem, feedback loops, constraints, the lot (Anatomy of an agent harness, LangChain). What I keep coming back to is one slice of that: defining the guidelines and the exit criteria. It includes the skills and system prompts that tell an agent how to do a task, but the part I care about is defining what "done" means — the validation criteria, the way a Ralph Loop does, by looping an agent against a fixed pass/fail check, in a fresh context window, until it's satisfied.
A naive version: define integration tests, and require all of them to pass before declaring a feature complete.
A richer version uses artifacts plus human approval. When a tech-lead agent declares completion, the coordinator checks whether a SYSTEM_DESIGN.md and tasks.json were actually written to disk, whether a critic agent explicitly signed off on those artifacts in STATE.md, and whether a human reviewed and approved the design — also tracked in STATE.md.
This exit-criteria slice is where the leverage turns out to be. LangChain's PreCompletionChecklistMiddleware "intercepts the agent before it exits and reminds it to run a verification pass against the Task spec" — and changing the harness alone, mostly around verification, took their coding agent "from 52.8 to 66.5" on Terminal Bench 2.0 — Top 30 to Top 5 (Improving deep agents with harness engineering, LangChain). Same model, better exit criteria, thirteen points.
Sandboxing belongs here too: it enforces the harness by providing physical boundaries.
Skill and Agent Evaluation
Model evaluation is a well-worn practice. You prepare a separate test dataset, run the model against it, and there are plenty of benchmarks across domains and dimensions.
When I first wrote this, I thought there was no equivalent for skills and agents — that I wasn't aware of benchmarks aimed at this. Checking my own notes, that's wrong, and worth correcting. SkillsBench bills itself as "The first benchmark for evaluating how well AI agents use skills", and it does roughly what I said didn't exist: "We evaluate both skill effectiveness and agent behavior through gym-style benchmarking", with tasks deliberately built to require "skill composition (2+ skills) with SOTA performance <50%" (SkillsBench, BenchFlow). So the premise that nothing exists is just false against my own knowledge base.
What I was gesturing at survives the correction, though, in narrower form. A dataset for evaluating skills and agents needs more complicated, often open-ended tasks — not solve this math problem, where the best answer is known and you can cleanly score it. The tasks look more like: produce a code review for a given PR (for a code-review skill or agent), or design a web interface for YouTube (for a design skill or agent). That feels much harder to score, and I'm not sure what a clean rubric even looks like.
But that's also less of an open problem than I assumed. LangChain's writeup on evaluating deep agents tackles exactly the open-ended case. Their first lesson is that "Deep agents require bespoke test logic for each datapoint" — each case gets its own success criteria rather than one shared evaluator — and for the un-scorable-seeming tasks specifically, "the quality of the final output matters more than the specific path taken by the agent" — a finding that holds "for more open-ended tasks like coding and research", and they scored it anyway (Evaluating deep agents, LangChain). So the honest version of my claim is narrower: skills-specific benchmarks already exist, and there are working patterns for scoring open-ended agent output — but it's early, the rubrics are bespoke per task rather than general, and broad open-ended agent benchmarking is still thin compared to the maturity of model eval.
Granting that a framework and dataset exist for some classes of skills and agents, you can do the thing I actually care about: evaluate and compare them — trading off time and token cost against quality, and potentially price, if skills and agents become things you sell.
Take it one step further. Instead of installing skills and agents by hand, you set a budget and let the agent figure out which it needs for a task. You stop worrying about pollution from installing too many: during the sandboxing phase, the agent dynamically picks the most suitable available skills and agents for the task description — or runs several variations in parallel and learns from the results. With benchmarks like SkillsBench scoring composition, and per-datapoint eval patterns for the open-ended cases, the budget-and-auto-select idea is a next step rather than a leap from a vacuum.
Sources
- Writing tools for agents, Anthropic — tools as a contract between deterministic systems and non-deterministic agents; more tools don’t always lead to better outcomes; MCP tool annotations for open-world/destructive actions.
- Building effective agents, Anthropic — the orchestrator-workers pattern behind planning as the agent’s defining act.
- The anatomy of an agent harness, LangChain — skills as progressive disclosure; the broad definition of a harness as everything that isn’t the model; Top 30 → Top 5 by changing the harness.
- mattpocock/skills — a real-world skill library; small, composable, user- vs model-invoked.
- Effective context engineering for AI agents, Anthropic — sub-agents with clean context windows returning 1,000–2,000-token summaries.
- Architecting an efficient, context-aware multi-agent framework, Google — larger context windows aren't the single scaling strategy; the context-explosion failure mode.
- Scaling managed agents: decoupling the brain from the hands, Anthropic — replaceable components; the ~60% p50 TTFT drop; why irreversible compaction can fail.
- Effective harnesses for long-running agents, Anthropic — progress-file + git artifact resumption; compaction alone isn't sufficient.
- How we built a virtual filesystem for our assistant, Mintlify — ChromaFs; ~46s → ~100ms session creation with built-in access control.
- How we built Claude Code auto mode, Anthropic — "Sandboxing is safe but high-maintenance"; classifiers as a complement.
- Improving deep agents with harness engineering, LangChain — the PreCompletionChecklist exit-criteria middleware; 52.8 → 66.5 on Terminal Bench 2.0.
- SkillsBench, BenchFlow — the first benchmark for how well agents use skills; gym-style, skill-composition tasks with SOTA <50%.
- Evaluating deep agents: our learnings, LangChain — bespoke per-datapoint test logic; scoring final-output quality for open-ended coding/research.