Logo
All posts

MCP and Agents

In this blog we will see why an agent's tools moved from the caller to the producer, and what an MCP server changes.

Gaurav Sen/9 min read

In November 2024, Anthropic open-sourced the Model Context Protocol (MCP), "a new standard for connecting AI assistants" to other systems.[1]

Until then, an agent's tools were written by the team that ran the agent. Since June 2023, developers had described their own functions to the model, and the model asked for one by name.[2]

Anthropic's post named the cost of that: "Every new data source requires its own custom implementation".[1]

Engineers who called other companies' APIs from an agent faced three problems:

  1. Every API needed a wrapper and a description, written by hand.
  2. When the API changed, the wrapper broke.
  3. The upkeep fell on the caller. The company that owned the API did none of it.

In this blog we will see why an agent's tools moved from the caller to the producer, and what an MCP server changes.

1. How does an agent call tools?

Let's say you run a travel app. Its customers search for flights, book tickets and change seats, in a chat.

The flight tools belong to the airlines. So when your app starts, its server connects to each airline and collects their tools: search_flights, book_flight, book_seat.

Your server on the left, one arrow right to the airline, a server with a plane on its corner. First the airline is an API, and the list on its right says APIs: search_flights, book_flight, book_seat and more. Then it is the airline's MCP server, and the same list says tools. This blog is about that one change.
Your server on the left, one arrow right to the airline, a server with a plane on its corner. First the airline is an API, and the list on its right says APIs: search_flights, book_flight, book_seat and more. Then it is the airline's MCP server, and the same list says tools. This blog is about that one change.

So multiple airlines, and now I get all of their tools, their definitions, and I am ready. This is in the startup of the app.

I can forward the user query to the LLM and tell the LLM, look, this is the user query, these are the list of tools. Which one should I call next?

The LLM might say, call these three tools, search flights in all three asynchronously.

All the decisions of course are by the LLM. The grunt work is being done by us.

OpenAI's documentation allows for those three calls.[3] It says: "The model may choose to call multiple functions in a single turn."

Your server makes them and returns the three results. Then the model picks a flight.

The LLM, on the left, replies to your server: search_flights, three times. Your server calls search_flights on all three airlines, on its right.
The LLM, on the left, replies to your server: search_flights, three times. Your server calls search_flights on all three airlines, on its right.

The model makes every choice, but only from the tool definitions your server hands it.

2. Wrapping an API as a tool

Have you ever wrapped someone else's API in a function? The model needs a definition for each tool. Your team can write the one for book_seat by wrapping the airline's API as a tool.

An API can be wrapped as tools. It can be done, but there are some problems. This is one of the reasons why MCP servers came up.

I was writing a wrapper. I literally took the URL and I had that function. Now I had to describe that function to an LLM. So it's tiring.

The code is brittle. So if I change the code, then I have to go and change the definition also.

This burden, this vigilance, is expected not of the producer but the caller. That's the problem. If I change my API tomorrow, your tool is going to break.

Your server holds a wrapper for each airline's API, and each wrapper calls its airline. Airline 2 has changed its API, so Wrapper 2 is red and its call stops short of the airline with a cross.
Your server holds a wrapper for each airline's API, and each wrapper calls its airline. Airline 2 has changed its API, so Wrapper 2 is red and its call stops short of the airline with a cross.

Three airlines with three APIs each mean nine wrappers and nine descriptions for your team to write. That's the tedium.

The brittleness comes from the airline. When it changes book_seat, your wrapper still calls the old API, and your tool breaks.

Fixing that takes two edits, because the wrapper and its description were written separately. The airline owns the API, but your team keeps watch over it.

So the upkeep of every airline's API falls on your team, the caller. The slide calls it the developer burden.

3. MCP flips the ownership of tools

What if the airline wrote the definitions itself?

So instead what we do is we flip this ownership. Whenever your API changes, my server should automatically update itself.

The producer of the API now also publishes its tools: their names, descriptions and parameters. A server that does this is an MCP server.

Your server is its client. It asks for the tools with one tools/list request.[4]

Each tool comes back with a name, a description and a schema for its inputs. Nobody on your team wrote them.

When the airline changes book_seat, its server can tell every client that its list changed, and your server asks for the list again.

The specification asks this of servers that declared the listChanged capability.[4] We followed that message in I already have an API. Why do I need MCP?

So the upkeep of book_seat now sits with the airline, the one company that changes it.

4. A tool call through an MCP server

Does the model see a difference? No. A customer asks your travel app for a flight. The model replies with a tool call for search_flights, as before.

The LLM, your server and the airline's MCP server in one row. The LLM's tool call for search_flights reaches your server, and your server carries it on to the airline.
The LLM, your server and the airline's MCP server in one row. The LLM's tool call for search_flights reaches your server, and your server carries it on to the airline.

Your server carries that call to the airline's MCP server and brings the response back. The decisions are still the model's, and the grunt work is still your server's.

The specification calls tools model-controlled, "meaning that the language model can discover and invoke tools automatically".[4]

The model discovers the same tools either way. Only the keeper of their definitions has changed.

With a wrapper, your team wrote each one and watched it. With an MCP server, the airline publishes its own, and your server fetches them.

Summary

  1. An agent's tools can belong to another company.
  2. The model picks the tools, and may ask for several calls in one turn, but only from the definitions it is sent.
  3. Wrapping an API as a tool is tedious and brittle. It puts the upkeep on the caller.
  4. An MCP server flips that: the producer publishes its own tools, and the client fetches them with tools/list.
  5. The model's side doesn't change. It still sends a tool call, and the caller's server still makes it.

Sources

  1. Introducing the Model Context Protocol, Anthropic, 25 November 2024.
  2. Function calling and other API updates, OpenAI, 13 June 2023.
  3. Function calling, OpenAI API documentation.
  4. Tools, Model Context Protocol specification, version 2025-06-18.
  5. Intro to Agentic Systems, the slides of the session.
WhatsApp