<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Arman Nourifar</title>
    <description>The latest articles on DEV Community by Arman Nourifar (@arman08).</description>
    <link>https://dev.to/arman08</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3367183%2F599bd8bd-f1c8-4aad-902d-b274e0eb3ece.jpg</url>
      <title>DEV Community: Arman Nourifar</title>
      <link>https://dev.to/arman08</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/arman08"/>
    <language>en</language>
    <item>
      <title>How AI context compression actually works, part 1</title>
      <dc:creator>Arman Nourifar</dc:creator>
      <pubDate>Sun, 06 Sep 2026 17:51:27 +0000</pubDate>
      <link>https://dev.to/arman08/how-ai-context-compression-actually-works-part-1-11pk</link>
      <guid>https://dev.to/arman08/how-ai-context-compression-actually-works-part-1-11pk</guid>
      <description>&lt;p&gt;I build &lt;a href="https://compresso.ai/" rel="noopener noreferrer"&gt;Compresso&lt;/a&gt;, a local AI compression layer, using different techniques like Headroom, Rtk and others we cut down on token usage costs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyf2a2ctwol1p5qoudil3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyf2a2ctwol1p5qoudil3.png" alt=" " width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Every request your coding agent sends is mostly things you've already paid for. The file it read three turns ago. The build log it scrolled past. The 500-row JSON blob a tool returned when the model needed four fields. All of it rides along on every single request, and all of it is billed again.&lt;/p&gt;

&lt;p&gt;Context compression is the fix, and it's worth being precise about what it is, because the word invites a misunderstanding.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Compression here does &lt;strong&gt;not&lt;/strong&gt; mean summarizing. No model paraphrases your context into something shorter and hopes the meaning survives.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Compression means the same information in fewer tokens: selecting what matters verbatim, re-encoding what's repetitive, and pointing back to what's already there. Densifying, not discarding.&lt;/p&gt;

&lt;p&gt;Here's how that actually works, technique by technique.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbbbrx943kkgni9snltfm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbbbrx943kkgni9snltfm.png" alt=" " width="800" height="545"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Route first, compress second
&lt;/h2&gt;

&lt;p&gt;The first step isn't compression at all, it's recognition. A local ML classifier looks at each block of content and decides what it is: a JSON payload, a build log, source code, a diff, prose. That takes a few milliseconds, on your machine.&lt;/p&gt;

&lt;p&gt;This matters because there is no universal compressor. What's safe to do to a build log, collapse 400 lines of &lt;code&gt;Compiling...&lt;/code&gt; into one, would be vandalism on source code. So each content type is routed to a compressor built for its shape, and anything the router isn't confident about &lt;strong&gt;passes through untouched&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This is also why honest benchmark tables have zeros in them. Grep results that are already dense, and source code the model actually needs to see: the router looks at both and does nothing. Doing nothing is a feature.&lt;/p&gt;

&lt;h2&gt;
  
  
  Repetitive structure: the JSON problem
&lt;/h2&gt;

&lt;p&gt;Tool outputs love to return arrays of near-identical objects. A hundred log events, five hundred search results, every one carrying the same keys and mostly the same values.&lt;/p&gt;

&lt;p&gt;A structure-aware compressor analyzes the array statistically: which fields vary, which are constant, where the values &lt;em&gt;change&lt;/em&gt;. Then it keeps the head, the tail, the change points, and drops the verbatim duplicates in between. Every item it keeps is an untouched original, same schema, same bytes, no generated text mixed in.&lt;/p&gt;

&lt;p&gt;Before, 500 items:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"level"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"info"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"service"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"api"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"msg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"request ok"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"level"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"info"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"service"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"api"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"msg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"request ok"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;496&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;more&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;nearly&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;identical&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"level"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"service"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"api"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"msg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"upstream timeout"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;504&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After: the first few, the last few, and that one error, because that's where the information was. Measured on a real 500-item payload: &lt;strong&gt;9,526 tokens → 1,614&lt;/strong&gt;, in 2 milliseconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Logs: keep the signal, fold the noise
&lt;/h2&gt;

&lt;p&gt;Build and test output is the most compressible thing an agent reads, and the most dangerous to compress naively. The rule: errors, warnings, and stack traces survive &lt;strong&gt;in full&lt;/strong&gt;, including chained exceptions, where the interesting frame is often three &lt;code&gt;Caused by:&lt;/code&gt; blocks deep. What gets folded is the repetition around them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   Compiling serde v1.0.203
   Compiling tokio v1.38.0
   ... 180 lines like this ...
error[E0308]: mismatched types
  --&amp;gt; src/pipeline.rs:214:9
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The error block comes through byte-for-byte. The 180 compile lines become a note that they happened. Measured: a 200-line build log went from &lt;strong&gt;2,412 tokens to 148&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lossless re-encoding: same facts, fewer bytes
&lt;/h2&gt;

&lt;p&gt;Some transforms don't select at all, they re-encode, with an exact inverse. Strip ANSI color codes. Collapse a line repeated 40 times into the line plus a count. Group grep hits under one file heading instead of repeating the path on every match:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/auth.rs:12: fn validate_token(
src/auth.rs:48: fn validate_token_expiry(
src/auth.rs:91: // validate_token is called from...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;becomes&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/auth.rs:
  12: fn validate_token(
  48: fn validate_token_expiry(
  91: // validate_token is called from...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Grep stays grep, diffs stay diffs, logs stay logs, the model reads them exactly as it would have. And each of these transforms is self-checking: if reversing it doesn't reproduce the original, or the result isn't actually smaller, the content ships unchanged.&lt;/p&gt;

&lt;h2&gt;
  
  
  Déjà vu: the same file, four times
&lt;/h2&gt;

&lt;p&gt;Here's the redundancy no per-block compressor can see. Your agent runs &lt;code&gt;cat pipeline.py&lt;/code&gt;. Two turns later, &lt;code&gt;git diff&lt;/code&gt; shows most of the same lines. Then a test failure prints twenty of them again. The same bytes, billed three times, on every request from then on.&lt;/p&gt;

&lt;p&gt;Cross-turn deduplication watches the whole conversation. When a later tool output contains a large span that already appeared verbatim earlier, the later copy becomes a compact pointer: &lt;em&gt;this content appeared in full above&lt;/em&gt;. The first occurrence is never touched, so the original is always physically in the context the model reads. And it's done carefully enough that earlier turns are never rewritten, which keeps provider-side prompt caching working, so the savings stack instead of fighting each other.&lt;/p&gt;

&lt;h2&gt;
  
  
  Nothing is ever truly gone
&lt;/h2&gt;

&lt;p&gt;The last piece is the safety net under all of the above: reversibility. When compression does set something aside, the middle rows of that array, the folded stretch of log, it's kept, locally, and the model gets a way to ask for it. If the model decides it genuinely needs row 247, it retrieves row 247. In practice it rarely asks, because the compressors keep what mattered. But the option is what makes the whole pipeline trustworthy: compression that can be undone is compression you don't have to think about.&lt;/p&gt;

&lt;h2&gt;
  
  
  This is what runs on your Mac
&lt;/h2&gt;

&lt;p&gt;Everything above runs locally, inside Compresso, on every request your agent makes, before the request is billed. No prompts leave your machine, and the parts that don't compress safely simply don't compress. Every plan includes the full pipeline; the tiers only mirror the Claude or ChatGPT plan you're already on.&lt;/p&gt;

&lt;p&gt;If you want to see the technique-by-technique numbers, including the ones where compression does nothing at all, they're on the &lt;a href="https://compresso.ai/benchmarks" rel="noopener noreferrer"&gt;benchmarks page&lt;/a&gt;. Or just &lt;a href="https://compresso.ai/" rel="noopener noreferrer"&gt;try it on today's session&lt;/a&gt;: five-day trial, no card up front.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>claude</category>
      <category>openai</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Why Human APIs fail as MCP tools (and how to fix them)</title>
      <dc:creator>Arman Nourifar</dc:creator>
      <pubDate>Thu, 28 Aug 2025 17:02:05 +0000</pubDate>
      <link>https://dev.to/arman08/why-human-apis-fail-as-mcp-tools-and-how-to-fix-them-10hm</link>
      <guid>https://dev.to/arman08/why-human-apis-fail-as-mcp-tools-and-how-to-fix-them-10hm</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;The Model Context Protocol (MCP) is a powerful way to expose your systems to AI agents. But a common mistake teams make is to take an API built for humans, auto-convert it to MCP tools, and expect agents to use it effectively.&lt;/p&gt;

&lt;p&gt;APIs designed for human developers follow a very different set of rules than APIs/Tools that serve AI agents in agentic workflows. What’s intuitive for a person is often overwhelming, inefficient, and error-prone for an LLM. If we want our agents to succeed, we need to design for them from the ground up — not just repurpose what we already have.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting the stage:
&lt;/h2&gt;

&lt;p&gt;Imagine you want to enable agents to use your flight booking system by converting the current APIs you have, and you ask your agent to find the cheapest direct flight to Paris in June, This is roughly the api calls your agent should make:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;airports&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="k"&gt;search&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;paris&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Find&lt;/span&gt; &lt;span class="n"&gt;Paris&lt;/span&gt; &lt;span class="n"&gt;airport&lt;/span&gt; &lt;span class="n"&gt;codes&lt;/span&gt;
&lt;span class="k"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;airlines&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="k"&gt;Get&lt;/span&gt; &lt;span class="k"&gt;all&lt;/span&gt; &lt;span class="n"&gt;available&lt;/span&gt; &lt;span class="n"&gt;airlines&lt;/span&gt;
&lt;span class="k"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;flights&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="k"&gt;search&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="n"&gt;origin&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;JFK&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;CDG&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;departure_date&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2024&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;06&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;01&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="k"&gt;Search&lt;/span&gt; &lt;span class="n"&gt;flights&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;June&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;st&lt;/span&gt;
&lt;span class="k"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;flights&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="k"&gt;search&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="n"&gt;origin&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;JFK&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;CDG&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;departure_date&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2024&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;06&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;02&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="k"&gt;Search&lt;/span&gt; &lt;span class="n"&gt;flights&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;June&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;nd&lt;/span&gt;
&lt;span class="k"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;flights&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="k"&gt;search&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="n"&gt;origin&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;JFK&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;CDG&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;departure_date&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2024&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;06&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;03&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="k"&gt;Search&lt;/span&gt; &lt;span class="n"&gt;flights&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;June&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;rd&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;Continue&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;each&lt;/span&gt; &lt;span class="k"&gt;day&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;June&lt;/span&gt;&lt;span class="p"&gt;...)&lt;/span&gt;
&lt;span class="k"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;flights&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;details&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="k"&gt;Get&lt;/span&gt; &lt;span class="n"&gt;detailed&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;each&lt;/span&gt; &lt;span class="n"&gt;flight&lt;/span&gt;
&lt;span class="k"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;flights&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;456&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;details&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="k"&gt;Get&lt;/span&gt; &lt;span class="n"&gt;detailed&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;another&lt;/span&gt; &lt;span class="n"&gt;flight&lt;/span&gt;
&lt;span class="k"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;flights&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;789&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;details&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="k"&gt;Get&lt;/span&gt; &lt;span class="n"&gt;detailed&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;another&lt;/span&gt; &lt;span class="n"&gt;flight&lt;/span&gt;
&lt;span class="k"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;flights&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="n"&gt;direct_only&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Filter&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;direct&lt;/span&gt; &lt;span class="n"&gt;flights&lt;/span&gt; &lt;span class="k"&gt;only&lt;/span&gt;
&lt;span class="k"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;flights&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;sort&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="k"&gt;by&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;order&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;asc&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Sort&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="n"&gt;ascending&lt;/span&gt;
&lt;span class="k"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;pricing&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;calculate&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="n"&gt;flight_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;passengers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Calculate&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;fees&lt;/span&gt;
&lt;span class="k"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;pricing&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;calculate&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="n"&gt;flight_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;456&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;passengers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Calculate&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;fees&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Problem: Human APIs Don’t Fit Well with Agent Workflows
&lt;/h2&gt;

&lt;p&gt;Developers want lots of small, composable endpoints they can stitch together in whatever way makes sense for their application. They often have many endpoints, parameters, and options so a developer can decide what to use and how to combine calls.&lt;/p&gt;

&lt;p&gt;Converting each of these APIs 1:1 to an MCP tool will create friction:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Too many options → harder for the agent to decide which call is correct.&lt;/li&gt;
&lt;li&gt;Unclear purposes → descriptions meant for humans don’t map cleanly to the agent’s decision process.&lt;/li&gt;
&lt;li&gt;Extra steps → an agent may need multiple calls to complete something a human would do in one mental step.
The result is an MCP tool that works in theory, but slows down or confuses the agent in practice.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Solution: Think Like an Agent
&lt;/h2&gt;

&lt;p&gt;Agents don’t explore the way humans do. They work toward goals by following reasoning chains. When deciding how to turn an API into MCP tools, imagine you’re telling the agent a story about what it can do and how it can act.&lt;/p&gt;

&lt;p&gt;Instead of exposing every possible endpoint, focus on clear, goal-oriented actions. Each tool should represent something the agent can immediately understand and execute — like “find a product by name” or “book a meeting” — not just a low-level function.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Agent Stories
&lt;/h2&gt;

&lt;p&gt;Netlify’s CEO, Mathias Biilmann, recently highlighted in his talk and article “Introducing AX: Why Agent Experience Matters” that agents are becoming one of the core “personas” they design for. Just as we think about user experience (UX) for humans, we should think about agent experience (AX) when building MCP tools.&lt;/p&gt;

&lt;p&gt;One way to guide design is to write agent stories: short scenarios showing how the agent might solve a problem using your MCP tools.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“A user asks the agent to find the cheapest direct flight to Paris in June. The agent uses the searchFlights tool with the destination and month, then picks the best flight with selectBestFlight tool based on the criteria it has (in this case lowest price).”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;By imagining these flows, you’ll see where you can simplify steps, combine related actions, or rename tools so their purpose is obvious. Now the new flow our agent will follow immediately is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;searchFlights&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;"Paris"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;month&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;"June"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;departure_city&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;"New York"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="k"&gt;Returns&lt;/span&gt; &lt;span class="n"&gt;top&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="n"&gt;cheapest&lt;/span&gt; &lt;span class="n"&gt;direct&lt;/span&gt; &lt;span class="n"&gt;flight&lt;/span&gt; &lt;span class="k"&gt;options&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="k"&gt;key&lt;/span&gt; &lt;span class="n"&gt;details&lt;/span&gt;
&lt;span class="n"&gt;selectBestFlight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;criteria&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;"cheapest"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Picks&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;lowest&lt;/span&gt; &lt;span class="n"&gt;priced&lt;/span&gt; &lt;span class="k"&gt;option&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;previous&lt;/span&gt; &lt;span class="k"&gt;search&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;

&lt;span class="o"&gt;#&lt;/span&gt; &lt;span class="k"&gt;Or&lt;/span&gt; &lt;span class="n"&gt;even&lt;/span&gt; &lt;span class="k"&gt;all&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;one&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt; &lt;span class="k"&gt;call&lt;/span&gt;
&lt;span class="n"&gt;findCheapestDirectFlights&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;"Paris"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;month&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;"June"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;departure_city&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;"New York"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;limit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Designing Flows for Agents
&lt;/h2&gt;

&lt;p&gt;When building MCP tools, think in terms of flows rather than just endpoints. A flow represents the sequence of actions an agent will take from start to finish for a given task.&lt;/p&gt;

&lt;p&gt;You can help the agent succeed by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Grouping actions that naturally belong together.&lt;/li&gt;
&lt;li&gt;Removing unnecessary branching that would force the agent to guess.&lt;/li&gt;
&lt;li&gt;Providing hints in tool descriptions about what comes next or what other options are possible.&lt;/li&gt;
&lt;li&gt;This doesn’t just make the agent faster — it makes it more reliable and less likely to get stuck.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Converting a human API into MCP tools is more than just an automated format change. By designing with agents in mind, using stories, flows, and goal-oriented thinking, you can create tools that work seamlessly in an agent’s reasoning process.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
