MCP Without Analogies

suzyahyah1 pts0 comments

MCP without analogies

Note: Edited in August 8 2026.

Preview

A lot of people talk about how MCP is a USB-C connector to Services and APIs on the internet. But I think this doesn’t really give people a proper appreciation of the picture, because it’s not that difficult to do integrations with REST-APIs or for LLM Agents to be exposed to functions directly without a client-server architecture.

Isn’t it straightforward to import googledrive and allow LLMs to go execute that function? Or to curl the API? Why do we need a new protocol?

First some Preliminaries

Here’s a workflow with MCP:

1) Human asks for the weather

2) Agent has a configuration file that tells it about available MCP servers

"mcpServers": {<br>"weather": {<br>"command": "python",<br>"args": ["/path/to/weather.py"],<br>"env": {}<br>},<br>"filesystem": {<br>"command": "node",<br>"args": ["/path/to/filesystem-server.js"]

3) Agent spawns subprocess for local server OR establishes a connection to the remote Server

4) Agent generates and sends JSON-RPC to the server

"jsonrpc": "2.0",<br>"id": 1,<br>"method": "tools/call",<br>"params":<br>"name": "get_alerts", "arguments": {"state": "CA"}

5) MCP Server processes and forwards query to the API or function call

6) External Tool or API returns a response and MCP Server formats this as JSON-RPC

"jsonrpc": "2.0",<br>"id": 1,<br>"result": {<br>"content": [<br>"type": "text",<br>"text": "Active alerts for CA:\nHeat Warning: Excessive heat..."

7) LLM-Agent Application formats the response

MCP from a functional point of view

We want to give LLM-Agents the ability to execute functions to overcome their limitations.

But this is ridiculously dangerous. If you give code execution control to an LLM or allow it to access an SDK (e.g., allow it to do code.eval()), there must be endless checks on what actually gets executed. The entire Google Drive API which has been exposed to human programmers may be more than what we’d like an LLM to be able to execute.

Perhaps we only give Agents read access (GET, no POST), but sometimes we want Agents to have some write access if we know those can happen reliably. Meaning, we need to control the kinds of write access they have gradually.

Hence a LLM-safe-access wrapper needs to be constructed to expose a subset of the full APIs and SDKs that we are prepared for Agents to hit.

The wrapper itself is thin. For instance, the following weather-mcp tool exposes get_alert and nothing else, no delete_forecast, no admin endpoints.

from fastmcp import FastMCP<br>import httpx

mcp = FastMCP("weather")

@mcp.tool<br>def get_alerts(state: str) -> str:<br>"""Active weather alerts for a US state (read-only)."""<br>r = httpx.get(f"https://api.weather.gov/alerts/active?area={state}",<br>headers={"User-Agent": "mcp-demo"})<br>return r.text

if __name__ == "__main__":<br>mcp.run() # stdio by default

Why not just have some piece of code that exposes only the “llm-safe” functions ?

That’s akin to a local MCP server, but using stdio as a transport protocol.

But why do we need to set up this stdio and separate client and servers. Can’t we directly expose these “llm-safe” functions to the Agent?

Technically we can, and that’s what LangGraph, OpenAI Agent SDK among others, did for exposing functions as Tool Calls. The main advantage of setting up server-client architecture and having a transport layer protocol is for applications to be language agnostic so that different programming languages can be used at different parts of the stack. For e.g., we may want the front end to be completely written in node, while the backend is in Python. That’s not unique to agents and AI engineering.

For LLM-providers doing agentic workflows at the backend, being language agnostic is really important because Claude might be optimised in Rust or C++ for performance, while the majority of the API callers use Node or Python.

Also, the server and code functionality isn’t always controlled at the AI Agent application / caller or client side, and so thinking of it as a service rather than a local piece of code is a more general scenario.

Ok so let’s assume I agree we should think of it as client-server architecture, but what is stdio, why not good old HTTP and REST API?

Good old http can work pretty well for most cases actually. Well, good old http ++. You may have read that REST is so-called “stateless” and cannot handle streaming, but REST API can be made stateful by sending a session cookie, and can maintain a streaming connection through streaming http which makes it sufficient for most chat applications.

In practice, it mostly depends if we are calling locally (stdio) or across machines over a network (streamable http). While stdio is typically only used for local, and streamable http can “easily” be used for both local and remote, if the AI agent is working locally, calling MCP servers by spinning up subprocesses has less overhead of spinning up a Web Server listening for HTTP Requests.

However, while I was researching this topic, I found that stdio is...

server agent weather stdio http agents

Related Articles