Part 4 of 6 · 5 min read
MCP and plain function calling
Covers: MCP and plain function calling; A checklist.
MCP and plain function calling
This is the first of the two questions interviewers ask at the end of Level 6.
My own sharper way to put it:
| Plain function calling | MCP | |
|---|---|---|
| What it standardises | how a model asks for a call (provider-specific) | how an application finds and calls tools on a separate program (provider-neutral) |
| Where the tool code lives | inside your application | in a server process or service you may not own |
| Who writes the tool | you | you, or someone else; reused by many hosts |
| How the model sees tools | function schemas | the same function schemas: the host converts |
| Discovery | you list them in the request | the client asks the server, at run time |
| Extra things | none | resources, prompts, and (modules 3 and 4) transports, notifications, sampling, elicitation |
| New risks | your own code | code and text from other parties: server authors, descriptions, results |
They are not alternatives. MCP sits under function calling: the host speaks MCP to servers and function calling to the model.
When not to use MCP. If the tools are yours, belong to one application, and will not be reused, plain functions behind your gateway are simpler, faster and have less attack surface: no extra process, no protocol layer, no third-party descriptions in your prompt. Reach for MCP when you want reuse across hosts, a boundary (a separate process or team), or someone else's integration.
Tip: an MCP server is an interface for an agent, not for a person
The protocol makes tools available; it does not make them useful. Module 1's narrow tools and module 6's server design are where that gets built.
A checklist
- One client per server, created by the host; the host owns the conversation.
- Never put the conversation into a tool argument unless that tool needs it.
- Prefix tool names with the server id before they reach the model.
- Convert tools to ordinary function schemas for the model; check which characters your model provider allows in names.
- Treat descriptions, annotations and results from servers as untrusted input.
- Ask a person for irreversible or costly calls, show the arguments, and return a "no" as guidance (module 1).
- Apply your gateway to MCP tools (scopes, row scope, caps, quotas, audit).
- Support both protocol eras in a client; probe, remember the answer, and re-probe if it fails.
- Return tool errors the model can act on; keep protocol errors for protocol problems.
- Use explicit handles for state, check them against the caller, and say how long they live.
- Do not use MCP for tools that are yours and used in one place, unless you want a boundary.
Interview angle
"How does MCP differ from plain function calling?" Say: function calling is how the model asks for a call, in a provider-specific format, with tools that live inside your application. MCP is how an application finds and calls tools that live elsewhere, over a standard protocol: a host creates one client per server, the client discovers the server's tools, resources and prompts, and the host then shows the tools to the model as ordinary function schemas. They stack: MCP does not replace function calling. Then give the trade: reuse and a clean boundary against more moving parts and a larger attack surface, since the descriptions and results come from third parties. Show you know the details that date a candidate: the protocol has an older handshake and session form and a newer stateless form where every request carries its version and capabilities, so a good client supports both. Weak answers say "MCP is a more advanced function calling" or "MCP is an API standard" and stop.
Second question of the level: "How would you secure an MCP server that exposes internal data?" The answer starts from module 1 (narrow tools, scopes, row scope, caps, short-lived credentials), then adds what comes next: authorisation of the client (module 5), validation of every input, treating server descriptions as untrusted in your own host, and logging every call.
Check yourself
A server returns isError: true with a message for a missing order. Is that a protocol error or a tool error, and who should see it? (A tool error. The call worked; the tool failed. It goes back to the model so it can adjust. A protocol error means the request itself was malformed or unknown.)
For the curious Why the spec changes under you
The protocol has two eras: a handshake with a session, and a newer stateless form. This module follows the specification pages read on 24 October 2026, which were under a draft path. Field and method names can move between revisions, so check them against the current specification before you build on them.
One bug found in the example: a message whose params was a list or a string, whose id was a list, or whose tool name was a list crashed the server instead of getting an error reply. The server now answers -32600 or -32602, and a test sends each malformed shape.
What you will use daily at work
| Practice | What it looks like |
|---|---|
| Reading JSON-RPC | Requests have an id; notifications do not; errors come back with a code. |
| Prefixing tool names | The host adds the server name so two servers cannot collide. |
| Consent before calling | The host shows the person what a tool will do before the first call. |
Draft: confirm which MCP revision your client and servers use.