An MCP server is a program that advertises capabilities — tools, resources, prompts — over a standard JSON-RPC protocol. A host application like Claude or Cursor runs an MCP client that connects to the server, asks what it offers, and lets the model invoke those tools mid-conversation. One protocol, any client, any server: that interchangeability is the entire point.
The three roles: host, client, server
The Model Context Protocol, introduced by Anthropic in late 2024 and since adopted across the major AI tools, splits the world into three roles. The host is the application the user sits in — Claude Desktop, Claude Code, Cursor, VS Code. The host embeds an MCP client, which manages protocol sessions. The server is a separate process — local or remote — that exposes capabilities: a filesystem server exposes file operations, a database server exposes queries, a web data server exposes search, scrape, crawl and map.
The model itself never speaks MCP. It emits a tool-use intention; the client translates that into protocol messages, runs the call, and feeds the result back into the model's context. That separation is why the same server works unchanged in every MCP-capable app.
The protocol under the hood
MCP is JSON-RPC 2.0 over a transport. Two transports cover practice: stdio — the client launches the server as a subprocess and they exchange newline-delimited messages over stdin/stdout, the standard for local servers — and streamable HTTP for remote servers, with the server free to stream partial output. A session starts with a handshake: the client sends initialize (protocol version, its capabilities), the server answers with its own, and from then on the client can list and call what the server advertised.
// client → server
{"jsonrpc": "2.0", "id": 7, "method": "tools/call",
"params": {"name": "search",
"arguments": {"query": "rtx 5090 price", "country": "de"}}}
// server → client
{"jsonrpc": "2.0", "id": 7, "result":
{"content": [{"type": "text", "text": "{ \"organic\": [ … ] }"}]}}Every request carries an id; every response echoes it. Errors come back as structured JSON-RPC errors rather than exceptions, which lets the model read a failure and adapt — retry with different arguments, or pick another tool.
What a server exposes
| Capability | What it is | Who initiates |
|---|---|---|
| Tools | Functions with JSON-schema inputs the model can call — search(query, country), scrape(url) | The model, during reasoning |
| Resources | Readable data identified by URI — files, records, documents | The application/host |
| Prompts | Reusable prompt templates the user can invoke | The user |
Tools dominate real usage. Each tool ships a name, a natural-language description and an input schema — and those descriptions are load-bearing: they are what the model reads when deciding which tool fits the task. A well-described tool gets called correctly; a vague one gets ignored or misused.
One tool call, end to end
- You ask: "What does an RTX 5090 cost in Germany right now?"
- The model recognizes its training data cannot answer a right now question and scans its available tools; the server's
searchdescription matches. - It emits a tool call with arguments — the client validates them against the schema and sends
tools/callover the session. - The server does its actual work — here, fetching a German results page through a proxy network and parsing it — and returns structured content.
- The result lands in the model's context; it reads prices from the organic results and answers, grounded in data fetched seconds ago.
Steps 2 and 5 are the ones MCP quietly revolutionized: discovery and grounding both happen without any application-specific glue code. We traced the differences from a plain REST integration in is an MCP server like an API.
MCP server vs RAG
The comparison comes up constantly because both fight stale knowledge. RAG retrieves from a corpus you built earlier — you own ingestion, chunking, embeddings, and freshness equals your pipeline's last run. An MCP server gives the model live capability — it fetches at question time, no corpus required. They compose naturally: agents use MCP tools to search and scrape the live web, and RAG to recall what the team already curated. When the knowledge you need is "the current state of the web", tools win; when it is "our 10,000 internal documents", RAG wins.
Security: the part the demos skip
An MCP server is code running with real permissions, called by a model that reads untrusted content. Three rules keep that sane. Scope the server's credentials to exactly what its tools need — a web-data server should hold an API key, never your cloud admin token. Treat tool output as untrusted input: a scraped page that says "ignore your instructions" is an injection attempt riding home in a tool result. And gate irreversible actions behind human confirmation; MCP's design keeps the human in the loop for exactly this reason.
A concrete example
Our web scraping MCP server is a typical production shape: an npm package launched over stdio by Claude, Cursor, Windsurf, VS Code or Cline, exposing eight tools — search, scrape, map, crawl, crawl_status, batch, batch_status and seo_audit. Each call hits the same REST API a developer would use directly, routed through residential proxies, billed pay-per-success. The server itself is a thin protocol adapter; the value sits behind it — which is the healthy architecture for any MCP server: capability in the backend, protocol at the edge. Setup for each client is in the docs.