
Twenty-Two Seconds Per MCP Call (and How We Fixed It)
TL;DR
~22s → ~0.4s per production call on the MCPBundles CLI (May 2026, my Mac). Five calls back-to-back: ~110s → ~2.2s. The MCP slice of make growth-refresh-report: 15+ min → ~53s.
I run MCPBundles. I'm biased. I'm also the person who kept running a fifteen-minute Makefile every morning and telling myself that was fine because "most of it is Playwright anyway" — which was sometimes true and often a cope.
The breaking point wasn't a benchmark chart. It was last Tuesday. I ran time mcpbundles call … on a Postgres pull we'd used in growth scripts for months because I didn't believe the numbers our benchmark script printed. 0.38s wall clock. I re-ran it thinking I'd mistyped --as. Same answer. I'd been eating ~22s of local CLI overhead on every call. Not Gmail. Not the Hub. The sidecar boot path. I'd normalized it because the alternative was rewriting a Makefile I'd already rewritten twice.

The Makefile I didn't want to touch
make growth-refresh-report sounds abstract. Concretely it's how I know whether yesterday's SEO clicks moved, who replied to warm outreach, who's paying, which accounts hit Sentry before support sees them, and whether any of that changes who we email this week. Under the hood it's a chain of pull scripts that each shell out to mcpbundles call against prod, then local Python merging jsonl into dossiers, outreach ranks, and the Cursor canvases we argue over in review. Same MCP tools customers use; we just wired them into Make because clicking five dashboards before standup is how you stop doing growth review entirely.
When each hop cost ~22s locally, I did what everyone does: I lied to the schedule. Skip-if-fresh flags. Trust yesterday's export. Run the heavy refresh twice a week and call it policy. We deleted those skips last week once calls got fast enough that "always fresh" stopped sounding like a vanity requirement. Incremental cursors still limit fetch volume; they never meant "skip the run."
After the speed work, a typical call looks like this on my machine:
$ time mcpbundles call postgres-execute-a94 --as mcpbundles_prod --bundle postgres -- sql="SELECT 1"
real 0m0.380s
Five of those in sequence land around 2.2s where they used to be ~110s. mcpbundles --version went from ~7s to ~0.3s. The full MCP leg of the morning stack finishes in ~53s where it used to block a calendar slot at 15+ minutes.
Session recording stills can still chew time when a week of new S3 blobs needs Playwright. That's a different problem. I'm not claiming we fixed video frames. We fixed the part where the CLI itself was the bottleneck.
Why shell latency matters more than chat latency
Cursor and Claude Code MCP is great when I'm in the loop. The growth stack isn't in the loop. It's a cron job and a Makefile and occasionally me alt-tabbing back from Slack wondering why the terminal hasn't returned.
The CLI is what those scripts invoke: discover tools, call, parse JSON. At ~0.4s you can fan across bundles, botch one, retry two, and finish before the human notices. That's the difference between "refresh nightly" and "refresh never because the script is embarrassing."
If you're on the MCP server inside your IDE, this paragraph isn't for you. I'm talking about pip install mcpbundles, named connections, and the sidecar path we dogfood internally.
Desktop
Most of the win showed up once a warm session handled terminal traffic instead of cold-starting every invocation. MCPBundles Desktop (menu bar, macOS and Windows, auto-updates) packages that idea. Preview builds are out. GA waits on Microsoft Store paperwork and one more VM smoke pass I'm not rushing. I'd rather ship slow than ship another "Needs attention" week.
Upgrade whatever you have installed and time a call you already run daily. CLI docs. Broader terminal-tool context lives in Best AI CLI Tools in 2026.