DEV Community

Cover image for MCP Resources vs Tools vs Prompts: 3 Layers That Cut My Agent's Tokens From 114K to 27K
Ken Imoto
Ken Imoto

Posted on Originally published at kenimoto.dev

MCP Resources vs Tools vs Prompts: 3 Layers That Cut My Agent's Tokens From 114K to 27K

Most MCP posts on this site stop at the Tools layer. That is the layer everyone builds first: get_weather(), send_email(), query_database(). It is also the layer that will eat your token budget if you leave it as the only thing you use.

The Model Context Protocol has three layers, not one. Resources, Tools, and Prompts. Each of them solves a different problem, each of them costs a different amount of tokens, and each of them is supported unevenly across clients right now. On the same browser-automation task, a CLI-style setup that pre-loaded the full tool documentation into the context ran at 114,000 input tokens. The MCP-native setup, where the server abstracted the low-level details away, ran at 27,000. A 4.2x cut without changing the model or the underlying browser — pulled from the case study in the Context Engineering book this article is adapted from.

Below is the concrete framework I use to decide which layer a piece of context belongs in, why the three layers cost so differently, and what to do when your MCP client only supports the layers it feels like supporting.

The 3 layers, side by side

Layer What it is When to use Cost profile
Resources Read-only information sources the model can pull on demand (file://, db://, api://) Static or slow-changing context the agent may need Cheap. Pulled only when referenced.
Tools Executable operations with side effects (create_file, send_email) Actions the agent takes in the world Moderate. Definition sits in context every call.
Prompts Reusable, parameterized templates the client can invoke Repeated flows: code review, ticket triage, incident response Cheap. Server-side; the client fetches on request.

Resources vs Tools vs Prompts: purpose, when to use, example, and token cost profile for each MCP layer.

Skip any of these three and you either lose expressiveness or you overpay in tokens. Both mistakes are common.

Why 114K → 27K happened

The 114K number came from a CLI-style approach to browser automation: dump the full command-line documentation, error handling, and usage examples for every primitive into the context, so the LLM knows how to compose them. Something like this:

# CLI-style design (114K tokens per run)
context = "Available CLI commands:\n"
context += generate_cli_documentation()   # 30 primitives, each with full docs
context += generate_cli_examples()        # example usage for each
context += generate_error_handling_docs() # every error code + retry strategy
# task itself: ~8K tokens sitting on top of ~106K of tooling documentation
Enter fullscreen mode Exit fullscreen mode

The 27K number came from an MCP-native rewrite where the server hides those details behind a small set of high-level tools. The chapter this article adapts frames it as roughly this:

# MCP-native design (27K tokens per run)
tools = [
    "playwright_navigate(url)",
    "playwright_click(selector)",
    "playwright_type(selector, text)",
    "playwright_screenshot()",
    "playwright_extract_text(selector)",
]
# server holds the CLI-level docs, retry policies, and error mapping internally
Enter fullscreen mode Exit fullscreen mode

The book credits three mechanisms for the drop:

  1. Abstraction level. CLI-style is low-level detail. MCP is a high-level abstraction. The client sends intent; the server figures out how to execute.
  2. Separation of context. The MCP server holds implementation details. The client only sees what it needs to decide the next action.
  3. Dynamic resolution. MCP resolves details when the tool actually runs. CLI-style has to describe everything up front, in case it is needed.

Where the three MCP layers come in is that each of them is one of those separation strategies. Tools are the intent layer. Resources are how the "docs the agent occasionally needs" get moved off the always-loaded context. Prompts are how the "repeat this whole flow again" logic gets moved onto the server. Together they are what makes the 4.2x abstraction gain possible in the first place.

The one-line takeaway from the chapter: your token bill is the description of the tools, not the tools themselves.

Which layer does a piece of context belong in?

The decision is not that hard once you have a rule. Here is the one I use.

Ask: does the agent need to do something, read something, or repeat something?

  • Do something → Tool. Side effects, mutations, external calls.
  • Read something → Resource. Read-only, addressable by URI, pulled on demand.
  • Repeat something → Prompt. Templates the client can invoke by name.

If you feel yourself dumping a full API doc into a tool's description field, stop. That is a Resource. If you feel yourself teaching the model the same 6-step recipe over and over in the system prompt, stop. That is a Prompt.

Tools are the loud, expensive layer because their definitions live in the context on every call. Resources and Prompts are the quiet, cheap layers because their content is fetched only when the agent decides it needs them. Most teams over-invest in Tools and under-invest in Resources and Prompts, then wonder why their agents feel expensive.

What your client actually supports right now (September 2026)

Here is the part nobody warns you about. The MCP spec has three layers. The clients do not implement all three uniformly.

  • Claude Desktop supports Resources, Tools, and Prompts. Prompts appear in the slash-menu inside the chat.
  • Cursor supports Tools well. Resource support has been improving through 2026 but is uneven. Prompt support arrived in a recent update and is now working end-to-end in the mcp.json config.
  • ChatGPT has been rolling out MCP since 2025 (Developer Mode beta shipped September 2025), with the Enterprise and Business rollout continuing into 2026. Tool support is solid. Resources and Prompts are still shipping.
  • Custom SDK clients (via the Python or TypeScript SDK) implement whatever you write. The floor is Tools; adding Resources and Prompts is trivial in the SDK and worth doing.

The practical takeaway is unglamorous. Even if your server exposes all three layers, some fraction of your users are on a client that only invokes Tools. Build your server so that a Tools-only client still gets meaningful behavior, and Resources and Prompts stack on top for the clients that can use them. Do not gate the core action on a Prompt the client will never call.

The July 28, 2026 spec revision helped here: capability discovery is now handled through the server/discover method, so a well-behaved client can at least ask what the server offers instead of assuming. Whether it actually uses what the server offers is a different question.

The design mistake I keep watching people make

The most common failure mode is not "picked the wrong layer." It is "put everything in Tools because Tools is the layer they understood first." I did this on my first two servers before I noticed the pattern. It is a rite of passage I would rather you skip.

Symptoms:

  • Tool descriptions running 500+ words each.
  • 30+ tools on the surface.
  • System prompt contains "when using tool X, remember to first check Y" instructions.
  • Token cost per turn is embarrassing.

The fix is almost always the same shape: collapse related low-level tools into an intent tool, move the docs the agent occasionally needs into Resources, and lift the repeated flows into Prompts. The MCP server picks up the orchestration; the agent stops paying for it in tokens.

The design principle behind this is the one line from the MCP guide I keep rereading: the description of the tool is context, and context has a price.

What to do this week

If you already run an MCP server, three concrete actions.

  1. Count the tokens your tool definitions consume on a typical run. If they are more than 20% of the total input budget, you have room to compress.
  2. Identify one thing you currently put in the system prompt or in a tool description that is really reference material. Move it to a Resource this week.
  3. Identify one multi-step flow you invoke often. Lift it to a Prompt so it lives on the server instead of being rebuilt in the client each time.

None of these three moves require rewriting your agent. They are configuration changes on the MCP server side, and the client will start benefiting the next time it connects.

If you want the longer walkthrough that this article is based on, my Zenn book Context Engineering: Turn LLMs From Liars Into Experts has a full chapter on the MCP three-layer split, including the code snippets for the Playwright server refactor that got me from 114K to 27K.

References

Top comments (0)