cd /news/ai-agents/six-turns-to-two-what-we-learned-mea… · home › topics › ai-agents › article
[ARTICLE · art-158072] src=blog.strata.do ↗ pub= topic=ai-agents verified=true sentiment=· neutral

Six turns to two: what we learned measuring an MCP server against a plain API

0sql measured its MCP server against its direct-API chat dashboard demo and found Claude Code needed 6.4 model round trips and 17.4 seconds per question over MCP versus 2.0 round trips and 7.5 seconds when the field catalogue was visible before the first call, with accuracy rising from 95% to 100%. The eval ran 61 natural-language questions over a customer-service model with 26 tables and 532 fields on Claude Opus 5, most variants twice, across 13 rounds. 0sql attributed the gap to Claude Code truncating the roughly 39 KB of server instructions sent on connect to about 2,000 characters, plus a lazy ToolSearch round trip that disabling with ENABLE_TOOL_SEARCH=false removed, cutting round trips from 4.8 to 3.4.

by read5 min views22 publishedOct 12, 2026
Six turns to two: what we learned measuring an MCP server against a plain API
Image: Blog (auto-discovered)

We run 0sql, a semantic layer protocol and service that turns JSON query specs into analytical SQL queries. Our goal for the upcoming week is to launch MCP integration. But first we wondered how different would this be to our custom chat dashboard app demo. In that app we simply implemented localized function calling capabilities that hit our REST api directly. Of course, the main difference is purposeful system prompts to bootstrap the conversation. We figured there would be differences but was surprised by the magnitude.

The puzzle

Our own demo app, a chat dashboard that calls the 0sql API directly, answers a question in two model turns: one tool call to plan the query, one to explain the numbers. Claude Code talking to the same server over MCP needed six round trips and three times as long for the same questions. MCP is just function calling with a different envelope, so where did the extra turns come from?

How we measured

We built an eval: 61 natural-language questions over a customer-service model with 26 tables and 532 fields, covering filters, rankings, date buckets, window functions, period-over-period, shares, calculations, segments and cross-fact measures. Claude Code runs headless as a real MCP client with only our server’s tools. The spec it settles on is planned, run against the warehouse, and compared row for row with a reference. A pass means the same rows. Each variant ran the full set, most of them twice, on Claude Opus 5.

Thirteen rounds later, here is the trajectory:

  • Setup 1: First MCP server, Claude Code as installed:
    • 6.4 model round trips, 17.4 seconds per question, 95% accuracy.
  • Setup 2: Tuned server, Claude Code as installed:
    • 4.8 round trips, 14.9 seconds, 95% accuracy.
  • Setup 3: Tuned server, tool search off:
    • 3.4 round trips, 11.5 seconds, 95% accuracy.
  • Setup 4: Tuned server, field catalogue visible before the first call:
    • 2.0 round trips, 7.5 seconds, 100% accuracy.

The last one is the demo app’s setup exactly: query, then answer.

What the gap actually is

  1. The demo’s model starts with the catalogue. The MCP model starts blank. The demo pastes every measure and dimension into its system prompt, so its first action is the query. Through MCP the model has to discover the fields first, which is at least one round trip, and choosing from a search’s ranked results is also where its mistakes came from . MCP has a slot for this: a server sends instructions on connect, and ours now puts the catalogue of every branch the key may read in there, about 39 KB. Claude Code keeps roughly 2,000 characters of it and marks the rest**[truncated].** We checked by asking a headless Claude Code to quote what it saw. The same cap applies to tool descriptions. That one client decision is the entire difference between row three and row four.
  2. Claude Code adds a round trip of its own. It loads MCP tool definitions lazily behind a ToolSearch call. Setting ENABLE_TOOL_SEARCH=false removed it, and with the tool schemas visible from the start the model also ran its field searches in parallel. That setting alone took us from row two to row three.
  3. Each round trip carries the harness. Claude Code sends 40,000 to 96,000 tokens of context per model call, nearly all cached. The demo sends about 10,000. A round trip is still a few seconds.

We also tried going the other way: tell the model to write the spec from the question’s own words and skip discovery, with refusals carrying the nearest fields. Given a search tool, the model searched anyway. Without one, it wrote, got refused, and retried: the same three round trips, with worse accuracy. Nothing beats having the catalogue in front of the model before it starts.

What this means if you use 0sql from an agent

Seed the catalogue where your client reads it whole. On Claude Code that is a skill or your project’s CLAUDE.md, not the MCP server. Generate it rather than write it: a fields call with no arguments returns the catalogue of a branch as text, every field with its uid grouped by table, measures with their descriptions and synonyms. Put that text in the skill, with the instruction to write the spec from it and call sql directly. That is row four.

Turn off tool search for Claude Code. ENABLE_TOOL_SEARCH=false in the environment Claude Code runs in. One fewer round trip on every question, and better accuracy, because the model sees the full spec schema up front.

Let the server do the rest. The endpoint now takes query specs only, with the spec’s JSON schema in the tool definitions; sends the catalogue on connect for clients that pass instructions through; returns it whole from fields; and answers a refused field name with the nearest fields, their descriptions and their tables, so a wrong first guess costs one retry. Expect two turns, not six. With the catalogue seeded, a question is one sql call and the answer, at the same accuracy as a hand-tuned direct integration.

The general lesson

Two things have to be true for an agent to answer in one call: the server has to offer what the model needs up front, and the client has to show it. MCP covers the first. A server can send its catalogue the moment a client connects, and ours does. The second is out of the server’s hands. Claude Code shows the model about 2,000 characters of what a server sends and drops the rest, so on that client the catalogue has to come from the agent’s own instructions, a skill or a project file. The server’s part is to make producing that text a single call, which is what the no-argument fields call is for.

── more in #ai-agents 4 stories · sorted by recency
── more on @0sql 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/six-turns-to-two-wha…] indexed:0 read:5min 2026-10-12 · —