Mohammad Ghazi Vakili
CV

How AI Agents Use Tools: Function Calling and the Model Context Protocol (MCP)

Cover: tool use and MCP

A language model on its own can only produce text. It cannot check today’s weather, query your database or run a calculation. Tool use closes that gap, and the Model Context Protocol (MCP) is a fast-growing standard for plugging tools into AI applications. This article explains both, with code.

How tool use works

The model never runs anything itself. The pattern is always the same:

  1. Your program tells the model which tools exist, each with a name, a description and a schema for its arguments.
  2. When the model decides a tool would help, it replies with a structured request instead of prose: the tool’s name and a JSON object of arguments.
  3. Your program validates the request, runs the tool, and sends the result back to the model.
  4. The model reads the result and either answers or asks for another tool.

A tool definition is just a description and a JSON Schema. For example:

{
  "name": "get_weather",
  "description": "Current weather for a city. Use when the user asks about weather.",
  "input_schema": {
    "type": "object",
    "properties": { "city": { "type": "string", "description": "City name, e.g. Turin" } },
    "required": ["city"]
  }
}

And the loop that drives it looks like this (pseudocode, to show the shape rather than any particular SDK):

messages = [user_message]
while steps < MAX_STEPS:
    reply = model.generate(messages, tools=TOOLS)
    if not reply.tool_calls:
        return reply.text                      # the model is done
    for call in reply.tool_calls:
        args = validate(call.arguments)        # never trust model output blindly
        result = run_tool(call.name, args)     # your code, your permissions
        messages.append(tool_result(call.id, result))
raise BudgetExceeded

Two design rules fall straight out of this. First, tool descriptions are prompts: a vague description produces wrong calls, so write them as carefully as you would write instructions for a new colleague. Second, the loop is your safety boundary: validation, permissions and step limits live in your code, not in the model.

The integration problem

Once agents became useful, every AI application wanted the same connections: files, databases, issue trackers, calendars, internal APIs. Without a standard, each application had to write its own connector for each tool, so ten applications and twenty tools meant two hundred integrations to build and maintain.

The Model Context Protocol

MCP, introduced by Anthropic in late 2024 as an open standard and since adopted across much of the industry, tackles that multiplication. An application implements an MCP client once; a tool provider implements an MCP server once; any client can then talk to any server. Think of it as a USB-C port for AI applications. The specification and SDKs live at modelcontextprotocol.io.

HOST APPLICATION (chat app, IDE, your agent)LLMdecides which tool to callMCP clientspeaks the protocolFiles servertools · resources · promptsDatabase servertools · resources · promptsWeb API servertools · resources · promptsMCP
The host application contains the model and an MCP client. Each server exposes a capability, such as files, a database or a web API, in the same standard way.

A server can offer three kinds of things:

  • Tools: actions the model can request, such as “run this query” or “create this ticket”.
  • Resources: read-only data the application can load into context, such as a file or a record.
  • Prompts: reusable, parameterised prompt templates the user can invoke.

Servers can run locally as a subprocess talking over standard input and output, or remotely over HTTP, which is how hosted services expose themselves.

A minimal MCP server

With the official Python SDK, a server that exposes one tool takes a handful of lines:

from mcp.server.fastmcp import FastMCP

mcp = FastMCP("Demo")

@mcp.tool()
def add(a: int, b: int) -> int:
    """Add two numbers."""
    return a + b

if __name__ == "__main__":
    mcp.run()

The function’s name, type hints and docstring become the tool’s name, schema and description. Point any MCP-capable application at this script and the model can call add. Check the SDK documentation for the current API, as the ecosystem is moving quickly.

Security: treat tools as an attack surface

Connecting a model to real systems is powerful and dangerous in equal measure. A few rules of thumb:

  • Least privilege. Give each server the narrowest permissions it needs: read-only database credentials, a single directory, a scoped API token.
  • Untrusted text can carry instructions. A web page, email or document that a tool returns can contain text that tries to steer the model. This is called indirect prompt injection. Treat all tool output as data, never as commands.
  • Be careful combining capabilities. Access to private data, exposure to untrusted content and the ability to send data out are each fine alone, and dangerous together.
  • Confirm irreversible actions. Deleting, paying, publishing or emailing should need explicit approval.
  • Only install servers you trust, and review what they can do, as you would for any third-party code.

We cover this in more depth in how to evaluate and secure AI agents.

Where to go next

If you have not yet read it, begin with What is Agentic AI?. To see tools doing real work, agentic AI for science shows how agents orchestrate simulation software, and multi-agent systems covers what happens when several agents, each with its own tools, work together.