All posts
MCP education··5 min read

MCP vs function calling: what's actually different

MCP is not a replacement for function calling — it's the layer above it. Function calling is how a single model picks a tool and produces arguments; MCP is the open protocol that standardizes how tools are advertised, transported, and invoked across every model and client. In production you use both: tools live in an MCP server, hosts speak MCP to discover them, and each host translates to the model's native function-calling format at invocation time.

⌘
Command+K team
Platform engineering

The confusion

Engineers new to MCP often ask the same question: "isn't this just function calling with extra steps?" It looks that way at first — both let an LLM invoke typed functions. The difference is that function calling is a per-model capability, and MCP is a cross-model protocol. They operate at different layers, and the production pattern uses both.

Two different layers

  • Function calling — how a single model decides which tool to call and produces the arguments. Vendor-specific JSON schema.
  • MCP — how tools are advertised, transported, and invoked across hosts and models. Open spec, one wire format.

Analogy: function calling is HTTP. MCP is OpenAPI. You still need HTTP to talk; you use OpenAPI so every client knows what endpoints exist without bespoke documentation.

What breaks without MCP

  • Every model migration becomes a rewrite of your tool schemas.
  • Every new AI client (Cursor, Claude Desktop, internal widget) needs custom adapter code.
  • Tool descriptions get duplicated across codebases and drift.
  • You can't benefit from the growing library of community MCP servers (Linear, GitHub, Postgres, Slack, Stripe).

The production pattern

Your stack ends up looking like this:

  • Tools live in an MCP server you own.
  • The host (widget, Claude, Cursor) speaks MCP to discover them.
  • The host translates to the model's native function-calling format at invocation time.
  • Switching models means swapping a host config, not rewriting tools.

Concretely

Define create_issue once in your MCP server. The same tool now works in Claude Desktop, your in-product widget, Cursor, and ChatGPT's MCP support — no per-client glue.

When raw function calling is fine

  • One model, one client, no plans to change.
  • Prototype work where the tool surface will be thrown away.
  • Closed agent loops where no external client will ever invoke your tools.

Everywhere else, MCP is the smaller long-term bet. Start with one tool, see Build MCP.

FAQ

Is MCP a replacement for OpenAI function calling?
MCP replaces the integration layer, not the model capability. The model still uses function calling under the hood; MCP standardizes how tools are advertised and invoked across hosts so the same tool works with OpenAI, Anthropic, Gemini, Llama, and any future model.
Can I use MCP and function calling together?
Yes — this is the production pattern. Your tools live in an MCP server. The host (Claude, Cursor, your widget) speaks MCP to discover them, then uses each model's native function-calling format to actually invoke them. You write tools once.
What does MCP give me that function calling alone doesn't?
Portability across models and clients, runtime tool discovery, a resource concept for read-only context, a prompt concept for shareable templates, and a transport (stdio, HTTP+SSE, Streamable HTTP) that the entire ecosystem already speaks.
Is it overkill for a small project?
If you only ever target one model and one client, raw function calling is fine. If you might switch models, support multiple clients, or want community-built integrations, MCP pays for itself the first time you avoid a rewrite.

Keep reading

Go deeper