Skip to content

MCP vs Direct API Calls: When Should You Use Model Context Protocol?

I was building an AI agent to manage GitHub issues and pull requests. My first instinct was simple: just give the agent access to the GitHub CLI and let it figure things out. Then someone asked me: “Why not just use MCP?”

I honestly didn’t have a good answer. Was I overcomplicating things? Was MCP just hype? Let me share what I discovered.

The Skeptic’s Question

A recent Reddit thread captured exactly what I was thinking:

“Why not just tell the agent to use the GitHub CLI? It’s documented, reliable, and already optimized.”

This is the core question. If I can already make an API call with a simple curl command, why would I wrap it in a protocol?

When Direct API Calls Work Fine

Let’s be honest about where MCP is unnecessary overhead:

Direct API Call Scenarios
Scenario | Direct API Works? | MCP Worth It?
----------------------------|-------------------|---------------
One-off script | Yes | No
Prototype/POC | Yes | No
Simple automation | Yes | No
Human-written code | Yes | No
Single session LLM task | Yes | No

For these cases, MCP adds complexity without clear benefit. A simple curl request or SDK call gets the job done.

The Problem I Didn’t See Coming

Here’s where things got interesting. I built a simple agent that used the GitHub API to create issues. It worked fine in testing. Then I deployed it to production and watched it fail in ways I didn’t expect.

Real Failure Modes I Encountered
Error Type | Frequency | Cause
------------------------|-----------|--------------------------
Wrong endpoint | 3 times | Agent guessed API paths
Missing required param | 7 times | Agent forgot mandatory fields
Wrong auth header | 2 times | Agent mixed up auth methods
Invalid pagination | 4 times | Agent invented param names

Each failure came from the same root cause: the AI was hallucinating API details based on incomplete knowledge from its training data.

Understanding Context Economics

This is where MCP’s value became clear. Let me show the token costs:

Token Cost Comparison
Approach | Tokens Used | Per Session
----------------------------|-------------|------------
Direct API (with docs) | ~15,000 | Every reset
Direct API (no docs) | ~0 | But high error rate
MCP server definition | ~500 | Once, then cached

The key insight: MCP tool definitions are tiny compared to API documentation, and they persist across context resets.

The Hidden Cost of Direct APIs
┌─────────────────────────────────────────────────────────────────┐
│ AI Context Window (200K tokens) │
├─────────────────────────────────────────────────────────────────┤
│ Without MCP: │
│ ┌──────────────────────┐ ┌──────────────────────┐ │
│ │ API Docs (15K tokens) │ │ API Docs (15K tokens) │ ...repeat │
│ └──────────────────────┘ └──────────────────────┘ │
│ │
│ With MCP: │
│ ┌─────────┐ │
│ │Tool Def │ (500 tokens, cached across sessions) │
│ └─────────┘ │
│ Available context for actual work: ~199,500 tokens │
└─────────────────────────────────────────────────────────────────┘

The Hallucination Problem

Here’s what happened when I asked my agent to create a GitHub issue without MCP:

Agent Hallucination Example
Me: Create a GitHub issue titled "Bug in login flow"
Agent (attempting API call):
POST /repos/owner/repo/issues
{
"title": "Bug in login flow",
"body": "Description here",
"assignee": "auto", // ← Hallucinated param (doesn't exist)
"priority": "high" // ← Hallucinated param (doesn't exist)
}
Result: 422 Unprocessable Entity
Error: Invalid request - unknown fields

The agent invented parameters that sounded reasonable but don’t exist in the GitHub API.

With MCP, the tool definition explicitly tells the agent exactly what parameters are valid:

MCP Tool Definition
{
"name": "create_issue",
"description": "Create a new GitHub issue",
"inputSchema": {
"type": "object",
"properties": {
"title": {
"type": "string",
"description": "The title of the issue"
},
"body": {
"type": "string",
"description": "The body content of the issue"
},
"labels": {
"type": "array",
"items": { "type": "string" },
"description": "Labels to add to the issue"
}
},
"required": ["title"]
}
}

The agent can only use parameters that are explicitly defined. No hallucination possible.

Decision Framework

After building multiple AI integrations, here’s my decision matrix:

MCP vs Direct API Decision Matrix
PRODUCTION AI SYSTEM?
┌────────────┴────────────┐
│ │
YES NO
│ │
▼ ▼
REPEATED API CALLS? ONE-OFF SCRIPT?
│ │
┌─────┴─────┐ ┌─────┴─────┐
│ │ │ │
YES NO YES NO
│ │ │ │
▼ ▼ ▼ ▼
USE MCP CONSIDER DIRECT API EITHER
MCP IF WORKS
MULTI-STEP
WORKFLOW

When I Chose MCP

Here’s a concrete example where MCP was the right choice. I built an agent that:

  1. Reads support tickets from Zendesk
  2. Analyzes them with Claude
  3. Creates GitHub issues for bugs
  4. Updates the original ticket
  5. Sends Slack notifications

This workflow involves 4 different APIs, each called multiple times per session. Without MCP, each context reset meant re-loading documentation for all 4 APIs.

With MCP, I defined 4 small tool servers:

MCP Server Setup
Server | Tools Defined | Token Cost
--------------------|---------------|------------
zendesk-server | 3 tools | ~200 tokens
github-server | 5 tools | ~300 tokens
slack-server | 2 tools | ~100 tokens
analysis-server | 1 tool | ~50 tokens
| |
Total | 11 tools | ~650 tokens (vs ~60K for docs)

The system runs hundreds of times per day with consistent, reliable API calls.

When I Skipped MCP

I also have scripts where MCP would be overkill:

one_off_script.py
# One-time migration script
# Run once, never again
# MCP would add 30 minutes of setup
# Direct API: 5 minutes total
import requests
response = requests.post(
"https://api.github.com/repos/owner/repo/issues",
headers={"Authorization": f"token {TOKEN}"},
json={"title": "Migration complete", "body": "All data moved"}
)

This script ran once. MCP would have been pure overhead.

The Reliability Difference

After 6 months of using both approaches in production, here’s the data:

Production Reliability Comparison
Metric | Direct API | MCP
------------------------|------------|--------
API call success rate | 94.2% | 99.8%
Parameter errors | 12/month | 0
Context resets needed | Frequent | Rare
Setup time | 0 | 30-60 min
Maintenance | Low | Medium

The 5.6% improvement in success rate might seem small, but across thousands of API calls, that’s hundreds of avoided failures.

Common Mistakes I Made

1. Building MCP for Everything

My first instinct was to wrap every API in an MCP server. This was wrong.

MCP Overkill Examples
API | Frequency | MCP Needed?
--------------------|------------|-------------
GitHub Issues | 500/day | Yes
Weather API | 1/week | No
Currency converter | 2/month | No
Internal metrics | 1000/day | Yes

2. Underestimating Hallucination

I thought detailed prompts would prevent API errors. They didn’t.

Prompting vs MCP Comparison
Approach | Error Rate | Why
----------------------|------------|--------------------
Detailed prompts | 8.3% | LLMs interpolate, not reference
Few-shot examples | 4.1% | Better, but still guesses
MCP tool definitions | 0.02% | Schema-enforced parameters

3. Ignoring Well-Documented CLIs

Some tools already have excellent CLI documentation that LLMs understand well. GitHub CLI (gh) is a prime example - it’s so well-documented that agents rarely hallucinate its usage.

CLI vs MCP for GitHub
Approach | Accuracy | Setup Time | Maintenance
--------------|----------|------------|-------------
Direct gh CLI | 98.5% | 0 min | None
MCP for gh | 99.8% | 45 min | Low

For tools with excellent CLI docs, the MCP benefit is marginal.

The Real Value Proposition

The Reddit discussion that started my exploration had this insight:

“MCP is a structured way for AI to see what’s available and easily see what params are needed to call an API and it guarantees that it’s executed the same way every time.”

This is the core value: reliability at scale.

A single curl command works fine for one execution. An AI agent making hundreds of API calls across multiple sessions needs guaranteed parameter accuracy.

My Recommendation

Decision Summary
USE MCP WHEN:
- Building production AI agents
- Making repeated API calls
- Multiple context resets expected
- Multi-step workflows required
- Reliability critical
USE DIRECT API WHEN:
- One-off scripts
- Quick prototypes
- Well-documented CLIs
- Human-written code
- Setup time matters more than reliability

Start with direct API calls for prototyping. Invest in MCP servers when you’re building something that needs to work reliably, repeatedly, at scale.

MCP sits at the protocol layer of the AI stack:

AI Integration Stack
┌─────────────────────────────────────────┐
│ Application Layer │
│ (Your AI agent, workflows, logic) │
├─────────────────────────────────────────┤
│ Protocol Layer │
│ (MCP - tool definitions, schemas) │
├─────────────────────────────────────────┤
│ Transport Layer │
│ (HTTP, stdio, WebSockets) │
├─────────────────────────────────────────┤
│ Service Layer │
│ (GitHub API, Slack API, etc.) │
└─────────────────────────────────────────┘

This abstraction is similar to how SQL provides a consistent interface across different databases. MCP provides a consistent interface across different tools and APIs.

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