Tools without MCP: the glue every app writes
A model cannot run code; it can only ask for a function by name. Before MCP, every application had to describe your function and call it in its own way.
Here is a function a support model should be able to use, and the description a model API needs for it:
def lookup_order(order_id):
orders = {"A17": "blue mug, shipped", "B42": "desk lamp, processing"}
return f"Order {order_id}: {orders[order_id]}."
lookup_order_schema = {
"name": "lookup_order",
"description": "Look up an order by its id and say where it is.",
"parameters": {
"type": "object",
"properties": {"order_id": {"type": "string"}},
"required": ["order_id"],
},
}The description is a JSON Schema: a JSON description of the arguments, saying order_id is a required string. The model reads the name and description to decide when to use the tool, and the schema to write valid arguments.
Running what the model asked for
model_asked_for = {"name": "lookup_order", "arguments": {"order_id": "A17"}}
functions = {"lookup_order": lookup_order}
function = functions[model_asked_for["name"]]
print(function(**model_asked_for["arguments"]))The model answers with a name and arguments; the application looks the function up and calls it. This is the pattern from Python for AI, and it works.
The problem
That schema had to be written by hand, next to the function, and kept in step with it. Then it was written for one application only. A second application, say an IDE or another team's agent, needs the same function described in its own format and wired into its own loop. Ten tools and four applications is forty pieces of glue.
MCP moves the tool out of the application. Your functions live in an MCP server. Any application that speaks MCP asks the server what tools it has, gets the names, descriptions and schemas in one standard shape, and sends calls back to it. You write the tool once.
- Add a second function and its schema by hand. Count the places you would have to change if
order_idbecame an integer. - Ask for
"order_id": "Z9"and read the error. - Remove
"required"from the schema. What would stop a model from calling the tool with no arguments?
Little by little, you're building something great.