No history yet

MCP Server Architecture

From Local Script to Shared Service

You've built a Retrieval-Augmented Generation (RAG) script that can pull information from a local collection of PDFs. It's powerful, but it's also trapped. It only works when you run it directly. What if you wanted to give this capability to an AI assistant like Claude Desktop or an IDE like Cursor? You can't just hand it a Python script.

This is where the Model Context Protocol (MCP) comes in. MCP provides a standard way to wrap your local tool, like the RAG script, inside a server. This turns your standalone script into a reusable service that any MCP-compatible application can talk to. Instead of being an isolated tool, your PDF index becomes a native capability for a powerful AI host.

The MCP Triangle: Host, Client, Server

The MCP architecture involves three distinct roles. Understanding them is key to seeing how the whole system works.

  1. MCP Host: This is the front-end application the user interacts with. Think of Claude Desktop or the Cursor editor. The host provides the user interface and the core AI model.

  2. MCP Client: This is a component living inside the host. Its job is to speak the MCP language. When the user's request requires an external tool, the client finds the right server and handles the communication.

  3. MCP Server: This is your application. It's a program that wraps your specific logic, like the PDF RAG script, and exposes its capabilities over the MCP protocol. It listens for requests from a client, performs its task, and sends back the results.

MCP follows a client-server architecture where an MCP host — an AI application like Claude Code or Claude Desktop — establishes connections to one or more MCP servers.

This separation allows for a flexible and powerful system. Your RAG server doesn't need to know anything about the host's user interface, and the host doesn't need to know the details of how your RAG logic is implemented. They just need to agree on the protocol.

The Two Layers of MCP

The MCP protocol is structured in two layers: the Data Layer, which defines what is being said, and the Transport Layer, which defines how it's being said.

Data Layer: What are we saying? (The content of the message) Transport Layer: How are we sending the message? (The communication channel)

This separation is powerful because it means you can use the same message format (Data Layer) over different communication channels (Transport Layer) depending on your needs.

Data Layer: JSON-RPC 2.0

The data layer of MCP uses JSON-RPC 2.0. This is a lightweight remote procedure call (RPC) protocol that uses JSON for its data format. In simple terms, it's a standardized way for the client to say, "Hey server, please run this function with these arguments," and for the server to reply, "Here is the result."

All MCP communication is built on a few core JSON-RPC methods, called primitives. The lifecycle of a connection begins with the mcp/initialize request. This is where the client and server introduce themselves and agree on the protocol version. After that, the server uses mcp/registerCapability to tell the client what it can do, such as providing a tool for querying PDFs.

// Client sends an initialization request
{
  "jsonrpc": "2.0",
  "method": "mcp/initialize",
  "params": {
    "protocolVersion": "1.0",
    "capabilities": {}
  },
  "id": 1
}

// Server responds with its capabilities
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "1.0",
    "capabilities": {
       "workspace": true
    }
  }
}

Transport Layer: Getting the Message Across

Once you have your JSON-RPC messages, you need a way to send them. MCP supports two primary transport methods, each suited for different scenarios.

STDIO

noun

Standard Input/Output. A standard communication channel between a program and its environment, consisting of standard input (stdin), standard output (stdout), and standard error (stderr).

The first method is STDIO. This is the simplest way to run an MCP server. The host application starts your server script as a child process. The host then writes JSON-RPC requests to your server's standard input (stdin) and reads responses from its standard output (stdout). This is perfect for tools that run on the same machine as the host, like a local PDF indexer or a file system tool.

The second method is HTTP with Server-Sent Events (SSE). This is for when your server is running remotely, perhaps on a different machine or in the cloud. The client connects to your server's HTTP endpoint. While the client sends requests via standard POST methods, the server can use SSE to stream responses and notifications back to the client. This is ideal for services that might take time to complete or need to provide real-time updates.

TransportUse CaseProsCons
STDIOLocal tools running on the same machine.Simple to set up, no network configuration needed.Limited to the local machine.
HTTP/SSERemote services, cloud-hosted tools.Accessible from anywhere, scalable.Requires network setup, handling HTTP complexities.

By wrapping your RAG script in an MCP server, you've created a modular and powerful tool. Any application that can speak MCP—whether locally via STDIO or remotely via HTTP—can now instantly gain the ability to query your PDFs. You write the logic once and share it everywhere.