Generated by Answer me with HTML 0.5.5 · 2026-10-17 12:34 · ★ Star on GitHub

MCP vs Calling APIs Directly

Explained with the GitHub example

Lead: Both ways end in the same GitHub API call. The difference is who writes and owns the GitHub code. With direct calls, your app owns it. With MCP, an MCP server owns it, and your app talks to that server in a standard way.

A

Answer

MCP wraps API calls; it does not replace them
  • Calling the API directly: your app holds GitHub-specific code: endpoints, auth, JSON formats, and a tool schema for each action.
  • MCP: the GitHub MCP server holds that code. Your app discovers its tools with tools/list and runs them with tools/call.
  • The same MCP client code works for GitHub, Slack, a database, or any other MCP server.
B

What changes in the architecture

question + toolsyour own API codeMCPAPI callsUserYour serverClaudeGitHub APIGitHub MCP server+
+3 added −1 removed

Use the Before / After switch to compare the two set-ups.

C

Side by side

Calling the API directly MCP
Interface GitHub's own REST / GraphQL Standard JSON-RPC methods
Who writes the GitHub code You The MCP server author
Tool schemas for Claude You write each one tools/list returns them
Tool descriptions You write them for the model Written for models by the server author
Adding Slack next Write it all again Connect one more server
Reuse in Claude Desktop or Claude Code Locked inside your app Any MCP host can use the server
D

Calling directly: your server holds GitHub code

your server · sketchpython
tools = [{  "name": "list_open_prs",  "description": "List open pull requests for a user",  "input_schema": {"type": "object",                   "properties": {"owner": {"type": "string"}}},}]def list_open_prs(owner):    return requests.get(        "https://api.github.com/search/issues",        params={"q": f"is:pr is:open user:{owner}"},        headers={"Authorization": f"Bearer {TOKEN}"},    ).json()

You repeat this for every action: repos, issues, projects, and every other area you need.

E

With MCP: your server holds no GitHub code

your server · sketch with the MCP Python SDKpython
async with ClientSession(read, write) as session:    await session.initialize()    tools = (await session.list_tools()).tools   # schemas from the server    # ... pass tools to Claude; Claude picks one ...    result = await session.call_tool(        "search_pull_requests", {"query": "is:open author:me"})

The same few lines work for any MCP server. The tool name here is illustrative.

F

One request, two layers

illustrative
ClaudeYour serverGitHub MCP serverGitHub APItool_use: search_pull_requests1MCP layer: same for every servertools/call search_pull_requests2API layer: specific to GitHubGET /search/issues?q=is:pr+is:open3GitHub JSON4MCP result content5tool result6
G

When to choose which

Situation Better choice
One or two simple endpoints Direct API calls
You need full control of requests, retries or caching Direct API calls
No MCP server exists for the service Direct API calls, or write an MCP server
Many actions across a large service like GitHub MCP
Several services in one app MCP
The same tools in your app and in Claude Desktop or Claude Code MCP
H

Analogy

Device plugs and a standard port

Each API is a device with its own plug. MCP is a standard port, and an MCP server is the adapter from one plug to that port. With direct calls, your app carries every plug itself.