I bookmarked a piece on ITNext called “Agent Skills and MCP: Finding the Balance” a couple weeks ago, because that’s exactly the question I had. I’d just wired an MCP server into an internal tool, then watched Anthropic ship Agent Skills, then watched a wave of posts declare MCP basically dead. I wanted someone to walk me through the actual tradeoff instead of a vibe.
The article opens well. It names the real criticism head-on: MCP’s capability negotiation dumps every tool’s full schema into context up front, whether you use it or not, and that costs tokens. Then, right as it’s about to get into the actual comparison, it stops and points you to the author’s newsletter for “a deep dive into MCP and Agent Skills.” The deep dive is behind a paywall I don’t have. So the free version tells you there’s a problem and then asks you to pay to find out what to do about it.
I don’t say that to be harsh, a short piece has to draw a line somewhere. But it left me exactly where the field guide listicles I’ve complained about before leave people: with the shape of the debate and none of the substance. So I did what I usually do. I built both versions of the same capability, counted the actual tokens, and then went digging into what Anthropic has shipped since that “MCP is dead” narrative started, because it turns out a lot has changed and almost nobody writing about this has updated their post.
Here’s what I found, including the part where I realized the debate itself is already out of date.
What MCP actually promises to solve
Quick grounding, because half the arguments online skip this. The Model Context Protocol is a standard interface between an AI client and external systems, tools, databases, files, other services. It defines three things a server can offer: tools (callable functions), resources (data the model can read, addressed by URI), and prompts (reusable templates). It also defines three things a client can offer back to a server: elicitation (the server can ask the user for more information), roots (the server is told what part of the filesystem it’s allowed to touch), and sampling (the server can ask the client to run a completion on its behalf, under the client’s control).
The pitch is portability. Write an MCP server once, and it plugs into any MCP-compatible client, Claude Desktop, Claude Code, Cursor, whatever else adopts the spec, without you writing custom integration code per client. MCP was donated to a vendor-neutral Linux Foundation body in late 2025 with the major model providers as founding members, which is a real signal that this layer is settling into infrastructure rather than staying a single vendor’s thing.
The criticism the ITNext piece raises is real, though: at connection time, an MCP client asks a server “what can you do,” and the server answers with the full JSON Schema for every tool it exposes. All of it. Whether the user’s request needs one of those tools or none of them. That’s the “your agent gets out of bed already carrying 50,000 tokens of tool definitions” problem people keep bringing up.
What Agent Skills actually do
Skills work differently by design. A skill is a folder: a SKILL.md file with YAML frontmatter (a name and a description), plus optionally more markdown files, reference docs, and executable scripts. Anthropic's own documentation lays out a three-level loading model:
Level 1 - Metadata (always loaded, every skill, at session start)
cost: ~100 tokens per skill
content: name + description only
Level 2 - Instructions (loaded only when a skill is triggered)
cost: under 5,000 tokens
content: the body of SKILL.md - workflow, examples, notes
Level 3 - Resources and code (loaded only as referenced)
cost: 0 tokens until something actually opens the file
content: extra reference docs, scripts run via bash,
only the script's OUTPUT enters context, not the code
That’s the entire trick: name and description are cheap enough to keep dozens of them sitting in context all the time, and everything expensive only loads once the model has already decided this specific skill is relevant to the specific request in front of it. It’s the same instinct as lazy loading in software, and it’s a genuinely different default than MCP’s original “list everything now” behavior.
I built the same 10 capabilities two ways and counted the tokens
Rather than trust either side’s marketing, I modeled a realistic issue-tracker integration (create issue, list issues, get issue, update issue, comment, search, assign, close, label, list projects) two ways: as an MCP server’s tools/list response with full JSON Schema per tool, and as ten Agent Skills with just frontmatter at rest.
A quick honest caveat before the numbers: I ran this locally without hitting a live tokenizer API, so I used the standard “about 4 characters per token” estimate that both Anthropic and OpenAI publish for back-of-envelope sizing, rather than an exact BPE count. The precise numbers would shift a little with a real tokenizer. The ratio between the two approaches won’t, because both texts are the same kind of content (English descriptions plus JSON punctuation), so whatever tokenizer quirks apply, they apply to both sides roughly equally.
import json
import re
# ~4 chars/token estimate, applied consistently to both sides
_word_re = re.compile(r"[A-Za-z0-9_]+|[^\sA-Za-z0-9_]")
def count(text: str) -> int:
pieces = _word_re.findall(text)
total = 0
for p in pieces:
total += 1 if len(p) <= 4 else -(-len(p) // 4)
return total
# MCP_TOOLS: 10 tools, full JSON Schema (name, description, inputSchema
# with typed properties and required fields) - modeled on a realistic
# issue-tracker MCP server
mcp_tools_json = json.dumps({"tools": MCP_TOOLS}, indent=2)
mcp_tokens = count(mcp_tools_json)
# SKILL_FRONTMATTER: 10 skills, Level 1 only (name + description)
skills_at_rest_text = "\n\n".join(
f"---\nname: {name}\ndescription: {desc}\n---"
for name, desc in SKILL_FRONTMATTER
)
skills_at_rest_tokens = count(skills_at_rest_text)
The full script, with all ten tool schemas and all ten skill descriptions written out, is longer than is worth pasting in full here, but the shape of it is exactly what’s above: build the same capability set twice, dump it to the string that would actually enter context, count it. Here’s what came out:
AT-REST COST FOR 10 EQUIVALENT CAPABILITIES
MCP tools/list JSON (10 tools, full schemas): 1,627 tokens
Agent Skills, Level 1 only (10 skills, frontmatter): 567 tokens
Ratio: MCP costs about 2.9x more at rest
One full SKILL.md body once triggered (create-issue): 584 tokens
Skills total if ONE skill triggers: 1,151 tokens
(vs 1,627 for MCP, which pays the full cost regardless of usage)
And scaling it up, since the interesting question isn’t 10 tools, it’s what happens at 50 or 100:
n tools/skills MCP (tokens) Skills L1 (tokens) Ratio
1 332 69 4.8
5 954 297 3.2
10 1,627 567 2.9
25 4,192 1,431 2.9
50 8,103 2,835 2.9
100 16,198 5,670 2.9
The ratio settles at roughly 3x once you’re past a handful of tools, and it’s linear on both sides, no surprise there, since neither side has any discovery logic in this version. That flat 3x is the honest, unglamorous version of the “MCP is bloated” claim. It’s real, but it’s a multiplier, not the “tens of thousands of tokens you’ll never get back” framing that a lot of the hotter takes lean on. My own toy example never got dramatic because ten tools with sane schemas just isn’t that much text. It gets dramatic at the scale real teams actually run into, which is exactly what I found when I went looking at what Anthropic itself has published.
Here’s the twist: MCP already fixed this
This is the part that made me feel like I’d wasted an afternoon building my own comparison, in a good way. The “MCP eats your context window” argument was accurate when Skills launched, and it is substantially less true now, because Anthropic shipped fixes for exactly this on both sides of the protocol within about seven weeks of Skills going out the door.
Oct 2025 Agent Skills ships. Three-level progressive disclosure
becomes the reference design for "load only what's needed."
Nov 4, 2025 Anthropic publishes "Code execution with MCP": instead of
calling MCP tools directly, the agent explores a
filesystem of tool definitions (one file per tool) and
only reads the files it needs. Their worked example: a
Google Drive to Salesforce workflow drops from 150,000
tokens to 2,000 - a 98.7% reduction. The post explicitly
says this "ties in closely to the concept of Skills."
Nov 24, 2025 Anthropic ships the Tool Search Tool for the Claude
Developer Platform. Tools can be marked defer_loading:
true; Claude sees a search tool plus your most-used
tools, and only expands full definitions for what it
searches for. Their published numbers: a setup with
five MCP servers (GitHub, Slack, Sentry, Grafana,
Splunk) that used to cost ~77,000 tokens up front drops
to ~8,700, an 85% reduction. Tool-selection accuracy on
their MCP evals went from 49% to 74% on Opus 4, and
79.5% to 88.1% on Opus 4.5, because the model isn't
drowning in irrelevant schemas anymore either.
Jan 2026 Tool Search gets wired specifically into Claude Code's MCP
handling, so this isn't just an API-level opt-in anymore,
it's the default behavior once your tool descriptions cross
roughly 10% of the context window.
Read that November 4th line again: Anthropic’s own engineering team describes the fix for MCP’s context problem in terms of Skills. Not “here’s an alternative to Skills,” but “this is the same idea applied to MCP.” Once tools live as discoverable files on a filesystem instead of a flat list dumped at connection time, and the agent reads only the ones it needs, you’ve built the exact same three-tier structure Skills already had: a cheap always-visible index, a mid-cost detail layer you load on demand, and a zero-cost layer (the actual tool code) that only matters once you’ve committed to using it.
So the framing that pit these two against each other was never quite right. It’s not “Skills solved a problem MCP has and MCP doesn’t.” It’s “progressive disclosure is the right shape for tool context, and both MCP and Skills now implement it, they just started from different corners of the problem.”
So what’s actually different between them now
If both use progressive disclosure, the real differences aren’t about context cost anymore. They’re about what each one is actually for and how each one runs.
MCP Agent Skills
Primary job Connect to external Package procedural
systems: data, tools, knowledge: how to do
services, other agents a specific task well
Client requirement Just needs to speak the Needs a code execution
protocol (request/response) environment (bash, a
sandbox) to read files
and run scripts
Portability One server, many MCP Open standard as of
clients across vendors, Dec 2025, growing list
governed by Linux of adopting tools, but
Foundation as of late 2025 younger ecosystem
Extra primitives Resources, prompts, None of these; a skill
elicitation, roots, is instructions plus
sampling - real protocol optional code, nothing
features beyond "call a more structured
function"
What executes The server, somewhere Whatever the client's
else, that you don't sandbox executes,
necessarily control locally to that run
Trust boundary You're trusting a You're trusting
remote server's whoever wrote the
implementation skill's bundled code,
which runs with your
session's permissions
The client requirement row is the one I underrated until I actually checked. Skills need somewhere to cat a file and run a script, so they only work where there's a code execution environment: Claude Code, the API with the code execution tool enabled, or claude.ai's sandboxed environment for the built-in doc skills. A bare chat client that just sends messages and gets text back genuinely cannot run a skill's Level 3 content, because there's no bash for it to shell out to. MCP has no such requirement. It's just a client asking a server to do something and getting an answer back, so it works in places Skills structurally can't, which is a real, non-cosmetic difference that survives the whole context-cost conversation being resolved.
The trust boundary row is the one I’d flag as underdiscussed. A skill can bundle a Python script that runs with your session’s permissions the moment the skill triggers. Anthropic’s own docs are blunt about this: only use skills from trusted sources, and audit anything you didn’t write yourself, because a malicious skill can misuse tools, exfiltrate data, or fetch compromised content, and it doesn’t need you to explicitly approve each action the way a tool call typically does. MCP servers carry their own version of this risk since you’re trusting whatever code the server runs on its end, but it’s a different shape of risk: you’re trusting a remote implementation you don’t control, rather than trusting local code that runs the instant it’s relevant.
Using them together: skill as playbook, MCP as hands
The framing I found most useful, and I want to credit where I saw it articulated clearest, comes from a piece describing an MCP server with over 330 tools alongside a matching set of skills: skills are the brain, they know what to do and when; MCP is the muscle, it actually does it. Once I stopped treating this as a versus question, that split matched what I’d want in my own setup.
Concretely: the MCP server I mentioned at the top exposes create_issue, search_issues, and friends as raw callable tools with typed schemas, no opinions attached. A skill sitting on top of it can carry the judgment that a bare tool schema can't express:
---
name: create-issue
description: Create a new issue in a project with a title, optional
description, labels, assignee, and priority. Use when the user wants
to file, log, or open a new issue or ticket.
---
# Create Issue
## Instructions
1. Confirm which project the issue belongs to. If there's only one
project in context, use it; otherwise ask.
2. Write a concise, specific title. Avoid vague titles like "bug" or
"fix this."
3. Infer priority from language cues ("urgent", "blocking", "when you
get a chance") but default to "medium" if unclear. Never guess
"urgent" without an explicit signal.
4. Before calling create_issue, call search_issues first to check for
an existing near-duplicate. If one exists, ask the user before
filing a new one.
5. Call the issue-tracker MCP server's create_issue tool with the
assembled fields, then confirm back to the user with the issue ID
and a link.
None of that judgment (check for duplicates first, don’t default to urgent without a signal, ask rather than guess which project) belongs in an MCP tool’s JSON Schema. A schema can tell the model what shape of arguments create_issue accepts. It can't tell the model when it's a bad idea to call it yet. That's what a skill is actually for, and it's a genuinely different job than what MCP does, regardless of how efficiently either one loads into context.
The mistakes I’d flag before you build on this
Mistake What it actually costs you
------------------------------------------------------------------------
Assuming Skills replace MCP outright You lose the protocol features
(resources, elicitation,
cross-vendor portability) that
MCP has and Skills don't
Building a skill for a client with no The skill's Level 2/3 content
code execution environment never loads; you get a name
and description and nothing
else, silently
Treating a rough token estimate as exact Use estimates for shape and
direction (which approach
scales worse), not for
precise budgeting decisions
Trusting a downloaded skill or MCP server Both can run code or receive
without reading it first data with your session's
permissions; audit before use,
not after
Writing tool descriptions too thin for Tool Search and Skill matching
Tool Search or a skill's Level 1 to match both rely on the description
on text; a vague one-liner means
the right capability doesn't
get found when it's needed
Where I landed
If I’m being straight about what changed in how I think about this after actually building the comparison: I stopped asking “MCP or Skills” and started asking two separate questions. Does this need to talk to an external system, especially one other clients or vendors might also need to talk to? That’s MCP, and as of the Tool Search Tool and code-execution-with-MCP work, its context cost problem has a real answer now, not just a promise of one. Does this need to carry procedural judgment, house style, or a specific way of doing a task well, packaged with the code that does it? That’s a Skill, and it needs a code execution environment to actually work.
Most real systems I’d want to build need both, with the skill telling the agent when and how to reach for the tool, not replacing it. The ITNext piece that sent me down this path got the opening question right and then stopped exactly where the interesting part starts. I don’t think that’s a knock on the author so much as a sign of how fast this specific corner of the ecosystem is moving: an article that accurately described a real problem in early October would already need a rewrite by the following January. Measure before you pick a side. The ground moves under this stuff faster than the hot takes do.
Tags: mcp, agent-skills, ai-agents, llm, software-architecture, anthropic, context-engineering
Top comments (0)