I was playing with tool calling around August 2024, months before the Model Context Protocol (MCP) existed (it was released on November 25, 2024). Back then, there was no shared standard across vendors, so every tool was something you designed by hand, and you felt every wasted turn. We got a standard, and a lot of us skipped the design part, the part MCP server best practices are really about.
Since then, I’ve tried out a lot of MCP servers. Virtually every one that comes out for infrastructure, networking, and related systems, I’ve looked at and used, to see how and where it fits. I keep landing on the same quiet disappointment. Most of them aren’t broken. They aren’t insecure. They just stop short. The industry found a brand-new way to give agents tools, and we mostly used it to hand them the same plumbing we already had.
Let me break down the three types I keep running into, worst to best.
This is the most common one, and honestly, it makes me a little sad. Take an existing REST API, point a generator at the OpenAPI spec, and ship whatever falls out. It’s easy to see why. Here’s the whole thing:
It hands the agent our endpoints, not our capabilities, so the agent has to reverse-engineer the business logic one turn at a time.
Picture a simple, hypothetical question: “who has access to this resource?” With a 1:1 mapping, the dance might go like this. Call get_users_with_access, get back a list of groups. Call get_users_in_group, get back a list of user IDs. Call get_username_from_id, over and over, to finally resolve names and emails. The agent wanted names and emails in the first sentence. Instead it spent three different turns, N tool calls, a pile of tokens, and several chances to wander off course. We gave the model our internal data model and hoped for the best.
Here is that sequence, with illustrative numbers (2 groups, 5 users):
This is better. Instead of exposing every endpoint, you expose a search tool. The agent describes what it needs in plain language, and another model or agent behind the server figures out which tools, API paths, or queries are relevant and hands them back.
I like the intent here. It respects that the agent knows its goal better than your URL structure does. It scales to huge APIs without drowning the context window in tool definitions.
But it’s still multi-turn. The agent asks what’s available, gets pointed at the right call, then makes the call, then interprets the result. You’ve moved the guesswork around rather than removing it. It’s a better map, but the agent is still doing the driving.
Here is the same question, with an illustrative turn count:
This is the good stuff, and there’s so little of it out there. Here you design tools around outcomes, not endpoints. A single get_users_with_access call returns a clean list of users with their names and emails, because the server did the group-resolving, ID-chasing join work internally and handed back the thing the agent actually asked for.
The win is threefold. You minimize agent turns (each round-trip of tool call and response), so there’s less latency and less room to derail. You minimize tokens, because the agent isn’t wading through intermediate payloads it never cared about. And you return meaningful data, shaped for the decision the agent is trying to make.
Yes, this is more work. You have to think about what agents actually want to accomplish instead of mechanically wrapping your routes. That thinking is the entire job. Without it, what we ship is a proxy, not an agent tool.
Here is the same question again:
It’s whether the design work happens once, up front, or gets handed to the model at runtime, on every single call, forever.
How the three compare on that same question (qualitative, not measured):
| Type | Tool calls (illustrative) | Agent reasoning on intermediate output | Tokens wasted on intermediate payloads |
|---|---|---|---|
| 1: 1:1 API mapping | High (e.g. 8) | High | High |
| 2: Semantic search | Medium (e.g. 3+) | Medium | Medium |
| 3: Agentic abstraction | Low (e.g. 1) | Low | Low |
I don’t think anyone set out to ship Type 1. It’s what happens when generating a server takes four lines and designing a good one takes real thought. Incentives did the rest. “We have an MCP server” is a checkbox, and a generated server checks it.
If we want better, here’s where I’d start.
We need a shared vocabulary for this. Something like a maturity model that says “this server maps endpoints,” “this one searches,” “this one exposes outcomes,” so buyers and builders can tell the difference before they’ve burned a week finding out. The same goes for public benchmarks that score a server on turns, tokens, and task success instead of tool count.
Open source is well placed to close this gap, because the gap is mostly patterns, not proprietary technology.
Pick one MCP server you use or run. Ask it the most common real question you’d put to it, and count the tool calls. As a rule of thumb, if it takes more than two calls, you’ve found your first outcome tool.
Takeaway: Design MCP tools around the outcome the agent needs, not the endpoints you happen to have.
👉 Explore the guide on 78 Essential MCP Servers for AI-Driven Network Automation
👉 Learn more about the Itential MCP Server
See how Itential connects AI reasoning to governed execution across your entire infrastructure.