toolcall() ← all concepts

// concept · mcp vs function calling

Not rivals. Pick by reuse.

People treat MCP and function calling as competitors and pick wrong. They're not. One is how a single app calls a tool; the other is how every app reuses it. Here's the rule.

// what function calling is

You describe a tool to the model — a name, a description, and a JSON input schema. When it fits the request, the model emits a structured call. It does not run anything. Your code executes it and hands the result back. With Claude that's a tool_use block your app runs; with OpenAI, a function call you execute and return. Either way: you define the tool and you write the dispatch code, all inside one application.

# function calling, inside one app model emits get_weather({ location: "SG" }) your code runs it -> returns the result # lives only in this app

The pain

Now you want that same tool in your IDE assistant, in a desktop chat client, and in your own app. With plain function calling, every client re-wires the same tools by hand — its own definitions, its own dispatch code. M clients times N tools = M times N bespoke integrations. You're maintaining the same weather tool in three places.

# every client re-wires every tool client A -> defines + dispatches get_weather client B -> defines + dispatches get_weather client C -> defines + dispatches get_weather # M times N. it grows the wrong way.

What MCP adds

Put the tool behind a small MCP server — one program speaking a standard protocol. Any MCP client connects, runs the handshake, calls tools/list to discover what's there, and calls it. You write and maintain the tool once; every client gets it without re-wiring. M plus N, not M times N.

# one server, many clients weather MCP server exposes get_weather ^ ^ ^ client A client B client C # all discover + call it # M plus N. wrote it once.

What MCP actually standardizes: a handshake with capability negotiation (JSON-RPC over the wire), discovery (tools/list before any call), the primitives (tools, resources, prompts), and transport (stdio for local, streamable HTTP for remote, with auth). Support across AI clients is broad.

The honest part: MCP sits on top

MCP does not replace function calling. It's built on the same idea. The model still decides to call a tool. Your server still executes it. What MCP adds is the standard plumbing around that — discovery, the handshake, transport — so the tool is portable instead of hand-wired per client. Same tool, two questions: function calling answers "how does this app call it," MCP answers "how does every app call it without rebuilding it."

# same get_weather, two ways function calling define + dispatch, in THIS app MCP server define once, ANY client discovers + calls # MCP wraps tool use; it doesn't replace it

The decision rule

A few tools inside one app you control → plain function calling. Adding a server, a handshake, and a transport buys you nothing here. You want the same tools reusable across many clients — or shipped for others to plug in → stand up an MCP server. That's exactly when the protocol earns its keep.

# pick by reuse few tools, one app -> function calling reuse across many clients -> MCP server
Don't over-engineer. For one small app with a handful of tools, a protocol is pure overhead — an extra server, lifecycle, and transport you don't need. Reach for MCP when reuse is real, not before.

Sources: Model Context Protocol — introduction · MCP — architecture · Anthropic — tool use overview · OpenAI — function calling

One concept a week. Free.

The deeper, copy-paste version of each ToolCall short — in your inbox.

// total: 0.00 · spam: void · unsubscribe: one click