Do you know the moment when you're working on something, or maybe interacting in some other way with an LLM agent, and suddenly you get the message "You've reached your usage limit"? Now you need to wait for a reset, or maybe you can switch models, but it's just not as good as the one that reached the limit. Well, don't worry — under that message, somewhere, you'll find the option to add a credit card and see how many tokens it costs to keep interacting.
In a world where climate change continues to show its impacts — wildfires around the world, low water levels, and melting glaciers — saving tokens could mean saving a bit of the planet. If users can use their tokens efficiently, then the power needed to run AI models can be reduced, along with all the resources that go into it. We can get to a place where your PC at home can run an LLM model and it can do everything you need for work.
You can think of tokens as the currency of AI models, but that's not really all there is to it. Tokens are calculated differently by each model, and both input size and output size matter. As a rough rule of thumb, 1 token equals roughly 4 characters. For example, if I enter "My coffee machine does not turn on," this sentence has 34 characters, including 6 spaces. Most models strip out space characters to save tokens, so if we remove them we get 28 characters, which comes out to 28 / 4 = 7 tokens. Let's say your model costs similarly to Claude Fable 5 — 10€ per 1M input tokens and 50€ per 1M output tokens. Just for the input, you'd pay 0.00007€, and depending on how long the output is — say 300 characters — you'd pay around 0.00375€ for the output, so in total you'd pay almost 0.004€ for this one question.
Here is the simplified calculation:
Sentence: "My coffee machine does not turn on" → 34 characters (including 6 spaces) → without spaces: 34 − 6 = 28 characters
Input tokens: 28 characters ÷ 4 = 7 tokens
Input cost (10€ / 1M tokens): 7 × (10€ ÷ 1,000,000) = 0.00007€
Output: 300 characters 300 ÷ 4 = 75 tokens
Output cost (50€ / 1M tokens): 75 × (50€ ÷ 1,000,000) = 0.00375€
Total: 0.00007€ + 0.00375€ = 0.00382€
One thing we can't control when using LLMs like ChatGPT or Claude is how long the answer will be, or how much money we want to spend on the interaction beforehand. It gets very chaotic when you start using LLMs for coding, because if you give the LLM permission, it will run terminal commands, structure files, write code, pull information from MCP servers or skills, and so on. It's very easy to lose control if you use LLMs this way.
I asked myself how I could save tokens during development, or in general while working with AI. My goal was minimal-to-medium input and minimal output. To test this, I used Claude Code and tried setting up the same project three ways: without a framework and without an MCP server, with a framework but without MCP, and with a framework and an MCP server together.
Here are the results:
Table 1
| Vanilla Node (T1) | Next.js, no MCP (T2) | Next.js + MCP (T3) | |
|---|---|---|---|
| Input tokens | 50 | 51 | 14,800 (est.) |
| Output tokens | ~27,000 | 44,065 | 5,700 (est.) |
| Total tokens | ~27,050 | 44,116 | ~20,500 (est.) / ~30,200 (measured) |
| Cost | $0.675 | $1.102 | $0.217 |
The result was that the framework + MCP server approach used far fewer tokens — to be precise, it was almost 3.5x cheaper and used 2x fewer tokens.
The framework + MCP approach did involve some manual work. I had to install the MCP server and do the initial setup myself. Still, even with that manual work, the advantages are clear: you spend fewer tokens, you probably consume less power, and you save money. This might also mean that your usage and knowledge of LLMs is better than that of users who just consume large amounts of tokens.
I encourage all of you to use frameworks and MCP servers, and to test other AI protocols like A2A, ACP, ANP, and UCP, as they give the most relevant and fastest context to your LLM. Your results will probably be better too — I haven't tested this with hard evidence, but from what I can see, the structure and foundation of the project look solid.
Be mindful of your token usage, and keep the planet safe.
Below, you'll find the rest of the tables and the prompts used for this little experiment.
Claude Code v2.1.233, Model: Opus 5 (default)
Prompt: "Create a project which makes an API call to my endpoint and shows the response title, content, and author. Here is the endpoint URL: http://URL:8081/endpoint. Also list how many tokens you've spent to do the task, every step."
Table 2
| # | Step | ~Tokens this step | ~Cumulative |
|---|---|---|---|
| 1 | curl the endpoint (large JSON response) | ~9,500 | ~9,500 |
| 2 | Check node/npm, target dir | ~1,600 | ~11,100 |
| 3 | Write package.json | ~1,000 | ~12,100 |
| 4 | Write api.js | ~1,300 | ~13,400 |
| 5 | Write server.js | ~1,400 | ~14,800 |
| 6 | Write public/index.html | ~2,400 | ~17,200 |
| 7 | Write cli.js | ~1,000 | ~18,200 |
| 8 | Run CLI (echoes full article) | ~1,900 | ~20,100 |
| 9 | Server test — hit EADDRINUSE on 3000 | ~1,900 | ~22,000 |
| 10 | Server retest on 4300 | ~1,600 | ~23,600 |
| 11 | Edit default port | ~800 | ~24,400 |
| 12 | Write README.md | ~1,200 | ~25,600 |
| 13 | Summary | ~1,300 | ~26,900 |
Prompt: "Create a project using Next.js which makes an API call to my endpoint and shows the response title, content, and author. Here is the endpoint URL: http://URL:8081/endpoint. Also list how many tokens you've spent to do the task, every step."
Table 3
| # | Step | Tokens |
|---|---|---|
| 1 | List dir, check node, probe endpoint | 24,411 |
| 2 | create-next-app scaffold | 1,951 |
| 3 | Inspect scaffolded files | 396 |
| 4 | Write .env.local + drafts.ts | 1,251 |
| 5 | Write page.tsx | 972 |
| 6 | Read layout.tsx (surfaced AGENTS.md) | 164 |
| 7 | List bundled Next docs | 904 |
| 8 | Read docs index + app tree | 163 |
| 9 | Failed cd (stale shell path) | 1,960 |
| 10 | Read fetching-data guide | 204 |
| 11 | Grep for force-dynamic | 2,309 |
| 12 | Read caching guide | 397 |
| 13 | 3 edits (remove no-store/force-dynamic, metadata) | 2,156 |
| 14 | Build #1 — caught the static-prerender bug | 507 |
| 15 | Grep legacy caching guide | 770 |
| 16 | Read segment-config section | 302 |
| 17 | 2 edits restoring force-dynamic | 2,386 |
| 18 | Build #2 — confirms dynamic | 337 |
| 19 | Start dev server, fetch HTML | 846 |
| 20 | Diagnose port conflict | 206 |
| 21 | Verify rendered output on :3001 | 751 |
| 22 | Inspect author markup | 451 |
| 23 | Get dev server PID | 1,271 |
| Total | ~44,065 |
Table 4
| # | Step | Input (est.) | Output (est.) | Counter delta (measured) |
|---|---|---|---|---|
| 1 | Inspect project structure + locate docs | 400 | 130 | 468 |
| 2 | Read docs index + 01-app tree | 950 | 110 | 924 |
| 3 | List doc directories | 450 | 120 | 1,791 |
| 4 | Read fetching-data.md + route-handlers.md | 7,200 | 90 | 1,190 |
| 5 | Read app files, configs + caching.md | 3,000 | 120 | 11,043 |
| 6 | Read fetch.md + grep deprecations | 2,020 | 110 | 4,770 |
| 7 | Write lib/drafts.ts + route.ts | 80 | 600 | 4,197 |
| 8 | Write app/page.tsx | 40 | 1,650 | 2,496 |
| 9 | tsc --noEmit | 30 | 70 | 257 |
| 10 | Start dev server | 150 | 110 | 324 |
| 11 | Test /api/drafts and / | 250 | 330 | 765 |
| 12 | Verify content + lint | 200 | 230 | 821 |
| 13 | Previous summary message | — | 1,150 | ~1,200 |
| 14 | This message | — | 900 | — |
| Total | ~14,800 | ~5,700 | ~30,200 |