n4nAI

What is the Model Context Protocol? MCP explained

MCP is an open protocol standardizing how apps supply context, tools, and prompts to LLMs via client-server JSON-RPC. Learn architecture, examples, and myths.

n4n Team5 min read1,039 words

Audio narration

Coming soon — every post will get a voice note here.


The Model Context Protocol (MCP) is an open, JSON-RPC based standard that lets a host application expose structured context, tools, and prompts to a language model through a uniform client-server interface. In short, what is model context protocol but a USB-C port for AI integrations—instead of writing custom glue code for every data source, you implement one server and any MCP-aware client can connect.

How MCP works

Core architecture

MCP separates three roles: the host (the LLM-powered app, e.g., an agent loop), the client (the in-process connector that speaks MCP), and the server (the external process or service that exposes capabilities). The host owns the model call; the client handles protocol framing; the server owns the integration with a database, filesystem, API, or internal tool.

This separation means a server author never imports your agent framework, and your agent framework never links against the server’s native dependencies. Communication happens over a transport—typically stdio for local subprocesses or HTTP+SSE for remote servers.

Primitives

MCP defines four capability types:

  • Resources: read-only data blobs or text the server can surface (e.g., a file, a DB row, a config snippet). They are addressed by URI.
  • Prompts: parameterized message templates the server recommends to the model.
  • Tools: functions the model can call, with JSON Schema–defined inputs and structured outputs.
  • Sampling: a server-initiated request for the host to run a model inference (used for recursive summarization or decision-making inside the server).

A server advertises these via initialize and list_* RPC methods. The host decides what to present to the model based on policy.

Transport and lifecycle

The handshake is explicit:

  1. Client sends initialize with protocol version and capabilities.
  2. Server responds with its own version and supported primitives.
  3. Client sends initialized notification.
  4. Normal requests flow.

Over stdio, messages are newline-delimited JSON. Over HTTP, the client posts JSON-RPC to a URL and receives server pushes via SSE. Both sides can cancel in-flight requests with notifications/cancelled.

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "query_orders",
    "arguments": { "customer_id": "c_123", "limit": 10 }
  }
}

Why MCP matters

Decoupling integrations

Before MCP, every agent framework shipped its own tool abstraction. A Postgres tool written for LangChain didn’t plug into a custom Go agent. MCP makes the server the unit of reuse: write the Postgres MCP server once, and any host—Python, TypeScript, Rust—can consume it.

The host retains control. A server may advertise a tool, but the client can refuse to expose it to the model, require human approval per call, or sandbox the subprocess. Because servers run as separate processes (or behind authenticated HTTP), a compromised tool doesn’t inherently leak the model key.

Ecosystem effects

A common protocol lets tool authors target one spec instead of N frameworks. It also lets enterprises audit context exposure: the set of MCP servers a host mounts is a concrete inventory of what the model can touch.

If you route model calls through a single OpenAI-compatible endpoint such as n4n.ai, which fronts 240+ models and handles fallback, your MCP host can stay model-agnostic while the gateway deals with provider quirks. The protocol doesn’t care which backend produced the tokens.

A concrete example

Suppose you want your agent to read repo files and run a lint check. Instead of embedding fs logic in your agent, you mount two MCP servers.

# terminal 1: filesystem server
npx -y @modelcontextprotocol/server-filesystem ./src

# terminal 2: a hypothetical lint server (illustrative)
python -m mcp_lint_server --root ./src

A minimal Python host using the official SDK:

from mcp import ClientSession, StdioServerParameters
import asyncio

async def main():
    fs_params = StdioServerParameters(
        command="npx",
        args=["-y", "@modelcontextprotocol/server-filesystem", "./src"]
    )
    async with ClientSession(fs_params) as fs:
        await fs.initialize()
        tools = await fs.list_tools()
        # tools contains 'read_file', 'list_directory', etc.
        res = await fs.call_tool("read_file", {"path": "main.py"})
        print(res.content[:200])

asyncio.run(main())

The host now has a read_file tool it can pass to the model in the standard tool-calling format. When the model emits a read_file invocation, the host forwards it to the MCP client, which serializes the JSON-RPC call to the subprocess. The file contents come back as a resource the model can reason over. No custom parsing, no framework-specific decorator.

Common misconceptions

MCP is not a model training protocol

It carries context at inference time. It does not define fine-tuning, LoRA adapters, or weight updates. If you see “context protocol” and think embeddings training, that’s RAG pipeline territory, not MCP.

MCP is not tied to a single vendor

Although early implementations and the spec emerged from Anthropic, the protocol is open and has community servers for GitHub, Slack, SQL, and more. A TypeScript server runs against a Python host without permission from any model provider.

MCP does not replace RAG

Retrieval-augmented generation is a strategy; MCP is a transport. You can absolutely back an MCP resource with a vector search over your knowledge base. The protocol standardizes how the retrieved chunk reaches the model, not how you embed or index.

MCP is not a query language

It is not SQL, not GraphQL, not Cypher. It’s a remote procedure call surface with typed tools and URI-addressed resources. You won’t write “SELECT * FROM mcp”, you call tools/call with a schema-validated argument object.

MCP is not only for local subprocesses

The stdio transport is common for dev, but the HTTP+SSE binding lets you run a managed MCP server in your VPC and have multiple hosts connect. Authentication is up to the deployment—the spec defines OAuth 2.0 as a recommended flow for remote servers.

Building a server: what you actually implement

A server is a loop that reads JSON-RPC, dispatches to handlers, and writes responses. Using the Python SDK:

from mcp.server import Server
import mcp.types as types

app = Server("demo")

@app.list_tools()
async def list_tools() -> list[types.Tool]:
    return [types.Tool(
        name="ping",
        description="Returns pong",
        inputSchema={"type": "object", "properties": {}}
    )]

@app.call_tool()
async def call_tool(name: str, args: dict) -> list[types.Content]:
    if name == "ping":
        return [types.TextContent(type="text", text="pong")]
    raise ValueError("unknown tool")

if __name__ == "__main__":
    app.run(transport="stdio")

That’s the entire surface for a trivial tool. The client side handles serialization, lifecycle, and capability negotiation. You focus on the integration logic.

When to adopt it

If you have one agent and one data source, a direct function call is simpler. MCP earns its keep when any of these hold:

  • You maintain tools consumed by multiple host processes or languages.
  • You want to isolate untrusted integrations in a separate process.
  • You need an auditable boundary of what context the model can access.
  • You plan to swap model providers without rewriting tool adapters.

What is model context protocol in practice? A boring, well-specified RPC layer that removes the N×M integration tax between models and tools. That boredom is the feature.

Key takeaways

  • MCP is a client-server JSON-RPC protocol with resources, prompts, tools, and sampling.
  • The host keeps model and approval control; servers are interchangeable.
  • Use stdio for local, HTTP+SSE for remote; both speak the same messages.
  • It complements RAG and inference gateways; it does not replace them.
  • Adopt it when integration breadth or isolation matters more than a ten-line inline function.
Tagsmcpmodel-context-protocolai-agentsdefinition

Written by

n4n Team

The team building n4n — a single OpenAI-compatible API in front of 240+ models, with automatic fallback, load balancing and pay-per-token metering.

More from n4n Team →

All model context protocol (mcp) deep dives posts →