.NETMCPAI AgentsArchitecture

Function Calling vs MCP: When to Use Which in .NET

Should a tool be a C# method or an MCP server? A clear decision guide for .NET agents on when to use built-in function calling versus the Model Context Protocol.

You can give a .NET agent a tool two ways: write a C# method and register it (function calling), or connect to an MCP server that exposes tools over a standard protocol. Both end up as an AITool the agent can call — so which should you use? People often reach for MCP because it’s new and interesting, when a plain method would be simpler. This article is the decision guide.

For the mechanics, see the tool-using agent tutorial (function calling) and the MCP guide (MCP).

The one-line difference

  • Function calling = a tool that lives inside your app as a C# method. The agent calls it in-process.
  • MCP = a tool that lives in a separate server, spoken to over a standard JSON-RPC protocol. The agent discovers and calls it over stdio or HTTP.

Everything below follows from “in your process” versus “in a separate server.”

Reach for function calling when…

A local C# method is the right default for most tools:

  • The logic is yours and specific. “Look up this customer’s orders in our database” is your business logic — write it as a method, test it, ship it.
  • You want the least moving parts. No extra process, no protocol, no network hop. Just a method the agent can call.
  • It’s tightly coupled to your app’s data and types. In-process access to your services, DI container, and domain models is simpler than marshaling across a protocol boundary.
  • Latency matters. An in-process call has none of MCP’s transport overhead.

If you’re writing the tool anyway and only your agent will use it, function calling is almost always the answer. Don’t add a protocol you don’t need.

Reach for MCP when…

MCP earns its extra complexity when the tool needs to be shared or external:

  • You want to consume tools someone else built. Official MCP servers exist for GitHub, filesystems, databases, and more. Connecting to one is far less work than reimplementing it as C# methods.
  • The same tool must serve many clients. If a Python agent, a VS Code session, and your .NET agent all need the same capability, an MCP server exposes it once for all of them — no per-language reimplementation.
  • You want a clean boundary between the agent and the capability. Different team, different deployment lifecycle, different security domain — a server boundary maps to an organizational one.
  • You’re publishing a capability for others. Wrapping a tool (or a whole agent) as an MCP server lets anyone with an MCP client use it.

The theme: MCP is about reuse and interoperability across boundaries. If there’s no boundary to cross, it’s overhead.

A quick decision table

Situation Use
Tool is your own business logic, only your agent uses it Function calling
Consuming a pre-built tool (GitHub, filesystem, DB) MCP
Same tool needed by multiple agents/languages MCP
Lowest latency, tightest coupling to your app Function calling
Publishing a capability for others to call MCP
Prototyping, keeping it simple Function calling

You don’t have to choose globally

The best part: an MCP tool and a C# method are both just AITool to the agent, so a single agent can use both at once. A typical production agent has a handful of local C# methods for its own business logic and connects to one or two MCP servers for shared or third-party capabilities. Mixing them is normal and encouraged — the decision is per-tool, not per-agent.

Note: MCP tooling in .NET is still stabilizing, but the architectural trade-off here — in-process methods for your own logic, MCP for shared or external capabilities — is durable regardless of API changes.

Takeaway

Default to function calling for tools that are your own logic and used only by your agent — it’s simpler, faster, and easier to test. Reach for MCP when a capability needs to be reused across agents or languages, consumed from someone else’s server, or published for others. And remember it’s not either/or: a single .NET agent happily uses local methods and MCP servers together, choosing per tool. Use the protocol when you’re crossing a boundary — and skip it when you’re not.


Have a correction or a topic you want covered? Email mani.bc72@gmail.com.