Skip to content

MCP vs Direct API: Which Approach Wins for AI Agents?

I was building an AI agent system that needed to connect to multiple tools—search, storage, and a custom internal API. I started with direct API calls, thinking it would be simpler. Six months and 47 integration points later, I realized I’d created a maintenance nightmare. That’s when I discovered MCP (Model Context Protocol), and it changed how I think about AI agent integration.

Here’s what I learned the hard way about when to use MCP vs direct API calls.

The Problem: Integration Complexity Explosion

It started innocently enough. My team had 3 AI agents that needed to call 5 different tools. I wrote direct API integrations for each combination. That’s 15 integrations—manageable, right?

Direct API call example
import requests
API_URL = "https://api.example.com/v2/search"
API_KEY = "your-api-key"
def search_assets(query):
response = requests.post(
API_URL,
headers={"Authorization": f"Bearer {API_KEY}"},
json={"query": query}
)
return response.json()

Then we scaled. By the time we hit 5 agents and 10 tools, I was drowning in 50 bespoke integrations. Each new tool meant updating every agent’s integration code. Each new agent meant implementing every tool’s API all over again.

The math is brutal:

  • 2 agents × 3 tools = 6 integrations
  • 5 agents × 10 tools = 50 integrations
  • 10 agents × 20 tools = 200 integrations

This is the N×M problem, and it grows quadratically.

What I Got Wrong About MCP

I initially dismissed MCP as unnecessary abstraction. A Reddit thread echoed my skepticism: “Most teams shipping agents know exactly which APIs their agent will call. Direct API calls win on latency, token cost, and debuggability.”

And for simple cases, that’s true. If you’re building a cron job that calls one endpoint hourly, MCP adds nothing but complexity.

But here’s what I missed: MCP isn’t trying to replace APIs. It wraps them with a discovery layer optimized for LLMs.

The Architecture Difference

Direct API: N×M problem
Agent 1 ─┬─> Tool A (custom integration)
├─> Tool B (custom integration)
└─> Tool C (custom integration)
Agent 2 ─┬─> Tool A (custom integration)
├─> Tool B (custom integration)
└─> Tool C (custom integration)
Result: 6 integrations for 2 agents × 3 tools
MCP: N+M solution
Agent 1 ─┐
Agent 2 ─┼─> MCP Client ─┬─> Tool A MCP Server
├─> Tool B MCP Server
└─> Tool C MCP Server
Result: 5 implementations (2 agents + 3 tools)

MCP collapses the complexity from N×M to N+M:

  • Each tool exposes one MCP server
  • Each agent implements one MCP client
  • 5 agents + 10 tools = 15 implementations instead of 50

MCP’s Three Primitives

MCP provides three core primitives that map to familiar concepts:

PrimitiveMaps ToPurpose
ResourcesGET endpointsRead-only data access
ToolsPOST/PUT/DELETEActions that modify state
PromptsWorkflow templatesReusable multi-step instructions

The key difference is discovery. With direct APIs, I hardcoded every endpoint. With MCP, my agents discover tools at runtime.

MCP tool discovery and call
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
async def discover_and_use_tools():
server_params = StdioServerParameters(
command="python",
args=["mcp_server.py"]
)
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
tools = await session.list_tools()
for tool in tools:
if tool.name == "search_assets":
result = await session.call_tool(
"search_assets",
arguments={"query": "customer data"}
)
return result.content

Where MCP Shines: Hot-Swappable Tools

The Reddit discussion highlighted something I experienced firsthand: hot-swappable tools (score 7/10 importance).

Before MCP, adding a new tool per user session meant:

  1. Provisioning OAuth tokens per service
  2. Modifying agent harness code
  3. Redeploying the entire system

With MCP, I just spin up a new MCP server and register it. The agent discovers it automatically. No code changes. No redeployment.

This matters when you’re running multi-tenant AI systems where different customers need access to different tool sets.

Where Direct API Still Wins

I tried to use MCP everywhere. That was a mistake.

Mistake 1: Single-Endpoint Scripts

A nightly batch job calling one API endpoint? Direct REST wins. MCP adds latency, complexity, and failure points for zero benefit.

Mistake 2: High-Throughput Pipelines

Data pipelines processing millions of events per second should avoid MCP’s abstraction overhead. Direct API calls minimize request path latency.

Mistake 3: Deterministic Compliance Workflows

Financial transactions, regulatory reports, audit submissions—these require exact, repeatable behavior. API parameters are fully controlled. MCP introduces agent-driven decision-making that compliance teams rejected in my case.

Mistake 4: Token Efficiency

I thought MCP would save tokens. Actually, MCP tools can be less token-efficient than properly designed CLI + agent skill combinations. If your agent is just calling one tool repeatedly, the MCP discovery overhead wastes tokens.

Decision Framework

After several failed experiments, I built this decision matrix:

CriteriaChoose MCPChoose Direct API
ConsumerAI agent or LLMDeveloper or application
Integrations3+ tools in workflowSingle endpoint
DiscoveryTools change frequentlyEndpoints are stable
SessionMulti-step, context-dependentSingle request-response
GovernanceCentralized AI access controlPer-endpoint permissions
ThroughputModerate, context-richHigh-volume, low-latency

The crossover point: Teams running 3+ AI-connected integrations typically see MCP’s complexity reduction benefits.

Why MCP Matters Now

I didn’t adopt MCP just because it’s newer. The industry momentum is real:

  • Anthropic created MCP in late 2024, then donated it to the Linux Foundation in December 2025
  • OpenAI deprecated their proprietary Assistants API and adopted MCP (mid-2026 sunset)
  • The Agentic AI Foundation (Anthropic + Block + OpenAI) now governs MCP as an open standard

MCP is becoming the default protocol for AI agent tooling. Fighting it means swimming upstream.

The USB-C Analogy

Before USB-C, every device needed its own cable. I had drawers full of proprietary chargers.

MCP provides a universal connector between agents and tools—one protocol replaces dozens of bespoke integrations. Your REST endpoints still exist underneath. MCP just adds a discovery and session layer on top.

What I Do Now

Most of my enterprise architectures run both:

  • MCP as the AI-facing layer
  • APIs as the execution layer

For simple scripts and high-throughput pipelines, I stick with direct API calls. For multi-agent systems with dynamic tool landscapes, MCP is worth the learning curve.

The question isn’t “MCP or API?”—it’s “where on this spectrum does my use case fall?”

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments