Setup and Operational Complexity
With MCP, you either expose your data as an MCP server or build a client that connects to those servers — a two-sided, separate process. In Claude Code, you set it up via one of three transport options: remote HTTP (recommended), remote SSE, local stdio; misconfiguration can lead to errors. When adding an MCP server in VS Code, besides searching and installing through the Extensions view, you also have to pass an 'I trust this server' confirmation — an extra trust step. With native function calling, setup is a single step: you add a JSON Schema to the tools parameter of the API request, with no separate process or service management. If you want to measure the operational overhead of this surface, look at the release notes: the 'Add server' form and 'Remove' action for the MCP servers dialog in Claude Code's VS Code extension were only added in v2.1.261 — the tooling surface is still maturing. On the native tool-use side, there's no separate surface to manage at all.
Cross-Vendor Portability
MCP's official promise is clear: 'many tools like Claude, ChatGPT, Visual Studio Code, Cursor, and MCPJam support MCP — build once, integrate everywhere.' OpenAI's Responses API can also connect to any remote MCP server via the mcp tool type by supplying a server_url; so the same server works identically across Anthropic, OpenAI, and Cursor. Cursor also supports all of the stdio/SSE/Streamable HTTP transports and the interactive MCP Apps extension. With native function calling, the situation is the opposite: OpenAI's function definition and Anthropic's tool definition don't use the same JSON fields — the same schema can't be copied to both APIs as-is, and adaptation is required when switching vendors. For a team with a multi-vendor strategy, this difference is the most concrete structural advantage in MCP's favor.
Enterprise Permissions and Allowlist Management
On August 6, 2026, GitHub made the allowedMcpServers/deniedMcpServers setting GA, letting enterprise owners centrally control which MCP servers Copilot clients can run — with serverUrl, serverCommand, and serverName matchers, the policy operates 'fail closed'; it's supported in the Copilot app, CLI, and VS Code, and was extended to JetBrains on August 18. On the Claude Code side, managedMcpServers was added on September 2, 2026 (v2.1.259): organizations can centrally roll out HTTP/SSE servers to all users; servers that run commands (stdio/local) are deliberately kept out of this scope. Something to watch when setting up this layer is which file the settings live in: allowedMcpServers and deniedMcpServers are separate top-level keys, not nested under the permissions block. With native function calling, no separate, officially documented enterprise allowlist layer exists at this scale — control depends entirely on which functions your application code adds to the tools array.
Token Cost and Tool Discovery
Anthropic's documentation is explicit: the API builds a special system prompt from tool definitions — each tool's name, description, and schema go into the context in full. When the MCP connector is used, all tool schemas coming from the remote server are loaded the same way; MCP by itself doesn't save tokens — on the contrary, it can bloat the context with multi-tool servers. Both sides offer the same official solution to this known problem: Anthropic with tool_search_tool_regex/bm25 and defer_loading, and OpenAI with tool_search (gpt-5.4+ models only), deferring rarely used tools and loading them only when needed. MCP's server/discover RPC also provides automatic discovery by returning supported protocol versions and capabilities in a single request — native function calling has no such discovery mechanism, and schemas are written statically into the code.
Latency, Debugging, and Security Surface
Native (client-tool) function calling requires two full API round-trips: the model returns a tool_use block, your application code runs, and you send the result back as tool_result in a second request — but this whole chain is in-process, with no extra process. Anthropic's MCP connector eliminates the need for a separate client by connecting directly from the Messages API to remote servers; however, in a local stdio MCP setup, the extra JSON-RPC/IPC layer structurally adds more latency. On the security side, the difference is sharper: OpenAI officially warns that 'a remote MCP server you don't trust can leak everything that enters the model's context'; the very reason GitHub's allowlist feature exists is this risk directly. With native function calling, since the code runs in your own environment, there's no third-party server trust boundary — the security surface is structurally narrower. On the observability side, you can inspect the server on a separate surface with MCP's official Inspector tool; with native function calling errors, you're left relying on the vendor's general API log infrastructure.
Real Payoff in a Single-Model Scenario
MCP's concrete advantages — portability, centralized discovery, enterprise allowlisting — are all presented in the official documentation in the context of multi-client, multi-server, or enterprise scale. For a project working with a single model plus a small number of internal tools, none of these criteria come into play; the payoff of setting up a separate server process is low at this scale. Native function calling offers the opposite profile: fewer moving parts, a single API contract, no separate process. Neither Anthropic nor OpenAI has published an official comparison page titled 'MCP vs. function calling' — both present them in their own documentation as complementary rather than competing; in fact, the MCP connector itself is a server-tool type built on top of the native tool-use infrastructure. This shows that the question isn't 'which is better,' but 'which threshold has the project's scale crossed.'