<?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: Rererr</title>
    <description>The latest articles on DEV Community by Rererr (@rererr_a54bf8b2ccee).</description>
    <link>https://dev.to/rererr_a54bf8b2ccee</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%2F4026132%2F94408f80-73c9-4ab8-ab6c-991585d8e6e1.png</url>
      <title>DEV Community: Rererr</title>
      <link>https://dev.to/rererr_a54bf8b2ccee</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rererr_a54bf8b2ccee"/>
    <language>en</language>
    <item>
      <title>One agent web-fetch tool returned 4.6M tokens for a 3.9MB CSV. Another returned 909.</title>
      <dc:creator>Rererr</dc:creator>
      <pubDate>Sun, 12 Jul 2026 15:10:40 +0000</pubDate>
      <link>https://dev.to/rererr_a54bf8b2ccee/one-agent-web-fetch-tool-returned-46m-tokens-for-a-39mb-csv-another-returned-909-4dlo</link>
      <guid>https://dev.to/rererr_a54bf8b2ccee/one-agent-web-fetch-tool-returned-46m-tokens-for-a-39mb-csv-another-returned-909-4dlo</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; — I gave the same 3.9 MB Japanese-government CSV to five web-fetch tools that coding agents use. &lt;strong&gt;Jina Reader returned 4,593,027 tokens&lt;/strong&gt; (instant context death). &lt;a href="https://github.com/Rererr/amenbo" rel="noopener noreferrer"&gt;amenbo&lt;/a&gt; — my MCP server — returned a header preview plus a pointer to the raw file: &lt;strong&gt;909 tokens&lt;/strong&gt;. That ~5,000× gap is the headline, but the more useful finding is &lt;em&gt;why&lt;/em&gt; general-purpose fetchers break on Japanese pages at all. Harness + raw logs are in the repo; every number below is reconciled against them.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The problem this started from
&lt;/h2&gt;

&lt;p&gt;Point a coding agent at Japanese web pages — a gov data page, a Shift_JIS text archive, a CSV/PDF link — and you hit failures the English-tuned tools rarely warn you about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Shift_JIS / EUC-JP pages come back as mojibake&lt;/strong&gt; (they're still everywhere in Japan).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A single long page dumps hundreds of thousands of tokens&lt;/strong&gt;, nav + ranking widgets + banners and all, and your context dissolves.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PDF/CSV URLs return raw bytes&lt;/strong&gt;, or the tool downloads 16 MB to disk and stops.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So I stopped hand-waving about being "good at Japanese" and measured it, on real URLs, against the tools people actually use.&lt;/p&gt;

&lt;h2&gt;
  
  
  The setup
&lt;/h2&gt;

&lt;p&gt;Five tools, one JSON-RPC harness, seven Japanese URLs picked to be &lt;em&gt;the failure-prone types&lt;/em&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Form&lt;/th&gt;
&lt;th&gt;Why included&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;amenbo&lt;/strong&gt; (mine)&lt;/td&gt;
&lt;td&gt;MCP (stdio)&lt;/td&gt;
&lt;td&gt;two-stage fetch + CJK-tuned extraction&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;mcp-server-fetch&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;MCP (uvx)&lt;/td&gt;
&lt;td&gt;the official reference impl — the baseline&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Jina Reader&lt;/strong&gt; (r.jina.ai)&lt;/td&gt;
&lt;td&gt;HTTP API&lt;/td&gt;
&lt;td&gt;the most common URL→Markdown service&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Playwright MCP&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;MCP (npx)&lt;/td&gt;
&lt;td&gt;the browser-rendering representative&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;PixelRAG&lt;/strong&gt; &lt;code&gt;pixelshot&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;CLI&lt;/td&gt;
&lt;td&gt;2026's "stop parsing HTML, screenshot everything" idea&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;URLs: a Zenn tech article, a table-heavy Wikipedia page, a &lt;strong&gt;Shift_JIS&lt;/strong&gt; 1.2 MB novel (Aozora Bunko), a government open-data HTML page, a Japanese PDF, a 3.9 MB CSV, and a site that refuses plain HTTP clients. macOS / Node v26 / cold cache / one hit each. Text tokens use one shared CJK-aware estimator; images use Claude's &lt;code&gt;width × height ÷ 750&lt;/code&gt; visual-token estimate.&lt;/p&gt;

&lt;h2&gt;
  
  
  The numbers (tokens an agent actually pays)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;URL&lt;/th&gt;
&lt;th&gt;amenbo&lt;/th&gt;
&lt;th&gt;mcp-server-fetch&lt;/th&gt;
&lt;th&gt;Jina Reader&lt;/th&gt;
&lt;th&gt;Playwright MCP&lt;/th&gt;
&lt;th&gt;pixelshot&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;zenn&lt;/td&gt;
&lt;td&gt;4,679&lt;/td&gt;
&lt;td&gt;2,627 ⚠️truncated&lt;/td&gt;
&lt;td&gt;4,216&lt;/td&gt;
&lt;td&gt;9,049&lt;/td&gt;
&lt;td&gt;11,462 🖼️10 imgs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;wiki&lt;/td&gt;
&lt;td&gt;5,337 (p1/4)&lt;/td&gt;
&lt;td&gt;2,078 ⚠️truncated&lt;/td&gt;
&lt;td&gt;38,014&lt;/td&gt;
&lt;td&gt;55,970&lt;/td&gt;
&lt;td&gt;1,178 ⚠️incomplete&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;aozora&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;7,992&lt;/strong&gt; (p1/25)&lt;/td&gt;
&lt;td&gt;1,400 ❌mojibake&lt;/td&gt;
&lt;td&gt;329,380 ⚠️full dump&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;453,263&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;263,819 🖼️221 imgs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;gov&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;1,774&lt;/strong&gt; ✅+data links&lt;/td&gt;
&lt;td&gt;519&lt;/td&gt;
&lt;td&gt;26,983&lt;/td&gt;
&lt;td&gt;25,382&lt;/td&gt;
&lt;td&gt;13,355 🖼️12 imgs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;pdf&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;810&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1,329 ❌raw bytes&lt;/td&gt;
&lt;td&gt;802&lt;/td&gt;
&lt;td&gt;❌can't&lt;/td&gt;
&lt;td&gt;❌875×1px img&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;csv&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;909&lt;/strong&gt; ✅handoff&lt;/td&gt;
&lt;td&gt;2,669 ⚠️raw dump&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;4,593,027&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;❌16MB to disk&lt;/td&gt;
&lt;td&gt;1,186 ⚠️first screen only&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A few things worth reading slowly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The 3.9 MB CSV (the 5,000×).&lt;/strong&gt; Feeding an LLM a 3.9 MB CSV is pointless. amenbo returns the header row, a short preview, and a pointer ("110_home-visit-care [15.4MB] — , 104 more via &lt;code&gt;links filter:'*.csv'&lt;/code&gt;") so the agent can &lt;code&gt;curl&lt;/code&gt; + script the aggregation instead. Jina returned all 4,593,027 tokens. Same file, ~5,000× apart.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Shift_JIS novel (1.2 MB).&lt;/strong&gt; amenbo and Jina both decode it; the official fetch garbles it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;amenbo:            吾輩は猫である。名前はまだ無い。どこで生れたか…
mcp-server-fetch:  #### �� | �@��y�i�킪�͂��j�͔L�ł���B…   (mojibake, UTF-8 assumed)
Jina Reader:       吾輩（わがはい）は猫である。名前はまだ無い…       (decodes, but keeps furigana inline)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The catch is token volume. Jina returns the whole novel in one shot — &lt;strong&gt;329,380 tokens&lt;/strong&gt;, furigana and all (as of a 2026-07-12 re-run; it was a 503 error before). Playwright MCP paid &lt;strong&gt;453,263 tokens&lt;/strong&gt; for the accessibility tree and pixelshot &lt;strong&gt;263,819&lt;/strong&gt; visual tokens across &lt;strong&gt;221 image tiles&lt;/strong&gt;. amenbo strips the ruby and splits it into 25 token-budgeted pages (&lt;strong&gt;7,992&lt;/strong&gt; for page 1, fetch &lt;code&gt;page: 2&lt;/code&gt; for more). A &lt;code&gt;fetch&lt;/code&gt; that &lt;em&gt;can&lt;/em&gt; return 300–450k tokens breaks your context-management assumptions regardless of averages.&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%2Feraimdbh2g3wvt0d2c75.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%2Feraimdbh2g3wvt0d2c75.png" alt="Token comparison for the 1.2MB Shift_JIS novel: amenbo 7,992 vs Playwright MCP 453,263" width="800" height="534"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PDF &amp;amp; CSV.&lt;/strong&gt; Japanese public-sector data is made of PDFs and CSVs. amenbo extracts PDF text (810 tok) and hands off CSVs with a preview (909 tok). The official fetch returns &lt;code&gt;%PDF-1.7 %����…&lt;/code&gt; raw bytes; Playwright can't snapshot the PDF at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  Progressive disclosure: read the map before the territory
&lt;/h2&gt;

&lt;p&gt;The numbers above are full Markdown. But amenbo can return an &lt;strong&gt;outline&lt;/strong&gt; first — the heading tree with a per-section token estimate — so the agent fetches only the sections it actually needs. On the same pages, &lt;code&gt;mode: "outline"&lt;/code&gt; costs &lt;strong&gt;75–97% fewer tokens&lt;/strong&gt; than full Markdown:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;page&lt;/th&gt;
&lt;th&gt;markdown&lt;/th&gt;
&lt;th&gt;outline&lt;/th&gt;
&lt;th&gt;saved&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Wikipedia (prefecture populations)&lt;/td&gt;
&lt;td&gt;5,337&lt;/td&gt;
&lt;td&gt;659&lt;/td&gt;
&lt;td&gt;87.7%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aozora novel (Shift_JIS)&lt;/td&gt;
&lt;td&gt;7,992&lt;/td&gt;
&lt;td&gt;408&lt;/td&gt;
&lt;td&gt;94.9%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Zenn tech article&lt;/td&gt;
&lt;td&gt;4,679&lt;/td&gt;
&lt;td&gt;1,141&lt;/td&gt;
&lt;td&gt;75.6%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MDN JavaScript guide (English)&lt;/td&gt;
&lt;td&gt;2,816&lt;/td&gt;
&lt;td&gt;389&lt;/td&gt;
&lt;td&gt;86.2%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;(Re-measured 2026-07-12 on v0.2.0; logs in &lt;code&gt;bench/logs-2026-07-12/&lt;/code&gt;.) For an agent researching across many pages, deciding &lt;em&gt;how much to read before reading it&lt;/em&gt; is what keeps the context window alive — and it's language-agnostic, so it helps on English pages too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it fits (and where it doesn't)
&lt;/h2&gt;

&lt;p&gt;This isn't "replace everything":&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Jina Reader / Firecrawl&lt;/strong&gt; are great hosted crawling APIs. amenbo is the opposite trade-off: &lt;strong&gt;local, free, MIT, no API key&lt;/strong&gt;, built to fetch a handful of pages precisely. (On plain Markdown quality, Jina is genuinely equal — on the Zenn article both reproduced all 24 table rows and 5 code blocks. amenbo's edge is holding that quality &lt;em&gt;while&lt;/em&gt; dropping nav/banners and capping the page budget.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The official &lt;code&gt;fetch&lt;/code&gt;&lt;/strong&gt; is the baseline everyone has; amenbo is what you reach for when it returns mojibake or raw bytes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Playwright / Browserbase&lt;/strong&gt; are for browser &lt;em&gt;automation&lt;/em&gt;; amenbo is for &lt;em&gt;reading&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PixelRAG&lt;/strong&gt; is a screenshot-based retrieval index — a different, complementary layer, not a competitor to live fetching.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The niche, as far as I can tell, is unoccupied: &lt;strong&gt;the polite, local, free fetcher that also survives the Japanese web.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest part (weaknesses included)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Axis&lt;/th&gt;
&lt;th&gt;amenbo&lt;/th&gt;
&lt;th&gt;note&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Token use&lt;/td&gt;
&lt;td&gt;◎&lt;/td&gt;
&lt;td&gt;per-page cap + progressive disclosure; orders of magnitude on long/CSV&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Extraction quality&lt;/td&gt;
&lt;td&gt;○&lt;/td&gt;
&lt;td&gt;equal to Jina + banner removal — &lt;em&gt;not&lt;/em&gt; a blowout&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CJK handling&lt;/td&gt;
&lt;td&gt;◎&lt;/td&gt;
&lt;td&gt;decodes Shift_JIS, strips furigana, paginates (Jina decodes too but keeps furigana &amp;amp; dumps the whole novel; official fetch garbles it)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Non-HTML (PDF/CSV)&lt;/td&gt;
&lt;td&gt;◎&lt;/td&gt;
&lt;td&gt;only tool of the five doing both&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Error handoff&lt;/td&gt;
&lt;td&gt;○&lt;/td&gt;
&lt;td&gt;classifies the error and suggests the next move&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JS-heavy / anti-bot pages&lt;/td&gt;
&lt;td&gt;△&lt;/td&gt;
&lt;td&gt;Playwright et al. win here; amenbo has a system-Chrome fallback but &lt;strong&gt;implements no anti-bot circumvention&lt;/strong&gt; — it stops honestly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Search / indexing&lt;/td&gt;
&lt;td&gt;✕&lt;/td&gt;
&lt;td&gt;PixelRAG's domain; amenbo has no search (use both)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Speed&lt;/td&gt;
&lt;td&gt;△&lt;/td&gt;
&lt;td&gt;politeness first (per-domain serial, 1 req/sec) — not for fast crawling, by design&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;It identifies as a bot, respects robots.txt / Crawl-Delay, and when a site blocks it, it says so instead of working around it. That's a design choice, not a gap.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; amenbo
&lt;span class="c"&gt;# browser features (SPA rendering, screenshots), one-time ~170MB:&lt;/span&gt;
npx &lt;span class="nt"&gt;-y&lt;/span&gt; amenbo install-browser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Register with your agent (&lt;code&gt;.mcp.json&lt;/code&gt;): &lt;code&gt;{ "mcpServers": { "amenbo": { "command": "amenbo" } } }&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;There's also a CLI sharing the same core (&lt;code&gt;amenbo fetch &amp;lt;url&amp;gt; &amp;gt; page.md&lt;/code&gt;), and a copy-paste prompt for &lt;code&gt;CLAUDE.md&lt;/code&gt; / &lt;code&gt;AGENTS.md&lt;/code&gt; in the README so the agent uses progressive disclosure by default.&lt;/p&gt;

&lt;p&gt;If your agents touch the Japanese web, I'd like to know where amenbo breaks for you. The harness and raw logs are public — counter-tests welcome.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Repo: &lt;a href="https://github.com/Rererr/amenbo" rel="noopener noreferrer"&gt;https://github.com/Rererr/amenbo&lt;/a&gt;&lt;/strong&gt; · &lt;strong&gt;Benchmark: &lt;a href="https://github.com/Rererr/amenbo/tree/main/bench" rel="noopener noreferrer"&gt;&lt;code&gt;bench/&lt;/code&gt;&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;amenbo (アメンボ) is Japanese for "water strider" — the insect that skims across water without making ripples. MIT licensed. This is an English write-up of a &lt;a href="https://zenn.dev/rererr_engineer/articles/e571e5b6eb1d53" rel="noopener noreferrer"&gt;Japanese benchmark article&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>webscraping</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
