MCPMCP Python SDK 2.2 · Python 3.10+
0%
1
Curious builder0 XP earned · 300 to level 2
0 daysFinish a lesson to begin
Badge collection0 of 6 unlocked
24 small wins to finish your pathNext lesson

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:

Example
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

Example
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.

Try it yourself
  • Add a second function and its schema by hand. Count the places you would have to change if order_id became 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.