ByHeartAI
Intermediate8 min read

MCP Architecture

MCP's architecture is simple: a host app contains clients; each client talks to one server over either local stdio or remote Streamable HTTP; messages are JSON-RPC; remote MCP is now stateless.

Explain like I'm new to AI

Three nouns, two cables:

  • Host — the app you use (Cursor, Claude, your agent).
  • Client — a connector inside the host. One client per server.
  • Server — a program that wraps GitHub, your files, a database, etc.

The "cables" are transports. Local servers run as a subprocess and talk over stdio (stdin/stdout). Remote servers sit on the internet and talk Streamable HTTP.

Pick a transport:

When:
Same machine as the host
How:
The host starts the server as a subprocess and talks over stdin/stdout. Fast, no network.
Auth:
Credentials from the environment — not OAuth.
Example:
A filesystem or git server running on your laptop.
Local servers use stdio; remote servers use Streamable HTTP. Since 2026, HTTP MCP is stateless — no session handshake.

Mental model

The host is a power strip. Each socket is a client. Each plugged-in appliance is a server. The appliances don't talk to each other through MCP — they talk to the strip. If two servers must cooperate, the host/agent coordinates them.

How it works

Local (stdio): the host launches npx … or a binary, writes JSON-RPC to stdin, reads stdout. Credentials come from the environment. Fast, no network, great for files and git on your machine.

Remote (Streamable HTTP): the client POSTs JSON-RPC. Required headers include Mcp-Protocol-Version, Mcp-Method (e.g. tools/call), and Mcp-Name (the tool/resource name). Gateways can route and rate-limit on headers without parsing the body.

Stateless since 2026-07-28: there is no initialize handshake and no Mcp-Session-Id. Each request carries protocol version, client info, and capabilities in _meta. Optional server/discover exists if you want capabilities up front. Any replica behind a round-robin load balancer can handle any request.

If your app needs continuity (a multi-step upload, a cursor), mint an explicit handle and pass it as a tool argument. Don't hide state in the transport.

Real-world example

Cursor on your laptop: a stdio filesystem server plus a stdio git server, and a remote HTTP Linear server. Three clients, three servers, one host. A load-balanced Linear deployment doesn't care which replica sees the next tools/call.

Technical explanation

MCP messages are JSON-RPC 2.0. The host, not the model, is the RPC client. Typical methods: server/discover, tools/list, tools/call, resources/list, resources/read, prompts/list, prompts/get.

List/read results may include ttlMs and cacheScope so clients cache catalogs and keep prompt caches stable across reconnects (deterministic list order matters here).

When a tool needs input mid-call (confirm a delete, fill a missing field), the server returns resultType: "input_required" with the questions — Multi Round-Trip Requests (MRTR). The client retries the same call with inputResponses. That replaced always-open bidirectional streams for elicitation.

Deprecated (still work for ≥12 months, don't start new work on them): Roots, Sampling, Logging, and the old HTTP+SSE transport. Tasks moved to an official extension (io.modelcontextprotocol/tasks) with poll-based tasks/get.

Common mistakes

Common mistake

Keeping sticky sessions "because MCP is stateful." The 2026 core is not. If you need state, put a handle in the tool schema so the model can pass it — transport sessions were the thing that didn't scale.

  • Using OAuth on stdio servers (use env credentials) or API keys-in-config for remote servers (use OAuth).
  • Forgetting Mcp-Method / Mcp-Name on HTTP, so the gateway can't route.

When to use it

  • stdio for local, user-owned data. HTTP for shared, multi-user, or vendor-hosted servers.

When NOT to use it

  • Don't force HTTP for a local-only file server, and don't force stdio for a SaaS others must reach.

Alternatives

  • Direct HTTP APIs the host wraps itself — more work per host, no shared catalog.

Quick quiz

Question 1 of 3

What are the two main MCP transports?

Question 2 of 3

What did the 2026-07-28 spec change about remote MCP?

Question 3 of 3

True or false: if your app needs state across calls, you should hide it in a transport session.

Related concepts

  • Why MCP ExistsMCP exists to kill the N×M connector problem — without a shared protocol, every AI app rebuilds the same GitHub, Slack, and database integrations from scratch.
  • Consuming an MCP ServerA host consumes MCP by connecting a client per server, mapping the catalog into function calling, and enforcing allow-lists and approvals.

Further reading

NextTools, Resources, and Prompts

Last reviewed: 2026-09-04 · Written by ByHeart AI · Reviewed by ByHeart AI