Building Advanced Agents: Integrating MCP Servers
Function calling gives a model one ability: instead of answering in prose, it can emit a structured request to run a named function with arguments. Your code sees that request, runs the actual function, and feeds the result back. That is the whole mechanism, and it is genuinely useful.
But function calling says nothing about the parts around the model. You write each tool as a function, the SDK builds its schema from the signature and docstring, and you write the dispatch code that runs the function when the model asks for it and feeds the result back. All of that lives inside the app you wrote it in. Build the same tool in another app and you write it again. 10 tools across 3 apps is 30 implementations to maintain.
Consider a common scenario: you are developing 2 AI agents and you want both of them to be able to create issues on GitHub, upload files to Dropbox, and send messages in Discord. The LLM needs to understand 3 completely different APIs. Each service has its own authentication method, its own request format, its own error handling, and its own quirks. The application developer has to write and maintain 3 separate integrations (tools), and if a fourth service comes along, that means a fourth custom adapter. This applies to the second agent as well, so now you have six integrations to maintain. This is the M times N problem in action: every agent (M) needs to integrate with every service (N), leading to M times N integrations.
Tool calling MxN
MCP, published by Anthropic in November 2024, turns M times N into M plus N. You build a tool once as an MCP server. Any MCP-capable app (the client) can use it without you touching the app's code. Add a tool to the server, and every connected client sees the new tool immediately, because the client asks the server what it has at connect time instead of you declaring it by hand.
MCP M+N
MCP has 3 roles:
The host is the application you actually use: LM Studio, Claude Code, an IDE, or your own agent. It owns the model, the conversation, and the decision to use a tool at all. The host does not talk to servers directly.
The client is the connector the host spins up, one per server. It owns a single connection: it runs the handshake, asks the server what it offers, forwards tool calls, and carries results back. If the host connects to 3 servers, it runs 3 clients. The client is code inside the host, not a separate process.
The server is the capability provider, a standalone process that exposes tools, resources, and prompts. A GitHub server exposes "create issue". A filesystem server exposes "read file". It runs locally over stdio or remotely over HTTP, knows nothing about your model, and answers any client that speaks MCP.
MCP simplified architecture
(i) The Host holds clients, one client per server, each client wired to one server. The model lives in the host and never sees MCP. The client translates between the host's tool-calling format and the server's MCP calls. That translation layer is the whole reason a GitHub server you wrote once works in any MCP host without changes.
MCP does not change how the model decides to call something. The model still produces a tool-call request in its native function-calling format. The host translates the server's MCP tool list into that format, and translates the model's tool call back into an MCP call to the server. MCP is the catalog and the plumbing. Function calling is still the trigger.
| Dimension | Plain function calling | MCP |
|---|
Local AI Engineering with Ollama
Run, understand, customize, fine-tune, and build agentic apps on your own hardwareEnroll now to unlock all content and receive all future updates for free.



