# What is the Model Context Protocol (MCP)? A Developer's Guide to Stateless AI Communication

> Discover the Model Context Protocol MCP a stateless JSON-RPC standard for AI agents. Learn how to exchange model driven requests and responses efficiently for better AI communication.

- Repository: [Rohit Ghumare/ai-engineering-from-scratch](https://github.com/rohitg00/ai-engineering-from-scratch)
- Tags: deep-dive
- Published: 2026-08-26

---

**The Model Context Protocol (MCP) is a stateless, JSON-RPC-based protocol that enables AI agents to exchange model-driven requests and responses through versioned, metadata-rich messages without requiring persistent sessions or connection-scoped state.**

The Model Context Protocol (MCP) defines how modern AI systems communicate with external tools, resources, and prompts in a deterministic, cacheable manner. As implemented in the `rohitg00/ai-engineering-from-scratch` repository, MCP eliminates traditional handshake overhead while maintaining backward compatibility for legacy systems. This protocol provides a standardized interface for heterogeneous AI runtimes to discover and invoke capabilities safely.

## Core Architecture of the Model Context Protocol

MCP is built on JSON-RPC 2.0 and operates on a fundamentally stateless design philosophy. Every request carries complete protocol context, allowing servers to process each message independently without maintaining connection state.

### Stateless Per-Request Metadata

Unlike traditional protocols that rely on session initialization, MCP embeds all necessary context within each request's `_meta` object. According to [`phases/13-tools-and-protocols/06-mcp-fundamentals/docs/en.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/phases/13-tools-and-protocols/06-mcp-fundamentals/docs/en.md), every message must include:

- **Protocol version** (`io.modelcontextprotocol/protocolVersion`): Currently `2026-07-28` for modern implementations
- **Client capabilities** (`io.modelcontextprotocol/clientCapabilities`): Feature flags declaring what the client supports
- **Client identity** (`io.modelcontextprotocol/clientInfo`): Optional metadata including client name and version

```json
{
  "jsonrpc": "2.0",
  "id": 7,
  "method": "tools/list",
  "params": {
    "_meta": {
      "io.modelcontextprotocol/protocolVersion": "2026-07-28",
      "io.modelcontextprotocol/clientCapabilities": {},
      "io.modelcontextprotocol/clientInfo": {
        "name": "course-client",
        "version": "1.0.0"
      }
    }
  }
}

```

The server treats the `_meta` block as the sole source of protocol context for that specific request. This design eliminates the need for connection pooling or session management, making MCP servers horizontally scalable and fault-tolerant.

### Versioned Negotiation

MCP implements strict version negotiation to prevent protocol mismatches. When a client sends a request with an unsupported protocol version, the server responds with JSON-RPC error code `-32022` and a list of supported alternatives.

```json
{
  "jsonrpc": "2.0",
  "id": 9,
  "error": {
    "code": -32022,
    "message": "Unsupported protocol version",
    "data": {
      "requested": "2027-01-01",
      "supported": ["2026-07-28"]
    }
  }
}

```

As documented in the MCP fundamentals, clients can retry with a supported version after receiving this error. This explicit negotiation prevents silent failures and ensures deterministic behavior across different protocol eras.

## MCP Server Primitives

The Model Context Protocol defines three core server-side primitives that expose capabilities to AI agents: **Tools**, **Resources**, and **Prompts**. These primitives are discoverable, cacheable, and URI-addressed.

### Tools, Resources, and Prompts

Each primitive serves a distinct purpose in the AI-agent workflow:

- **Tools** (`tools/list`, `tools/call`): Model-controlled actions that perform computations or side effects. Tools are invoked explicitly by the model based on context analysis.
- **Resources** (`resources/list`, `resources/read`): URI-addressed data sources that provide context to the model. Resources follow a read-only pattern with stable identifiers.
- **Prompts** (`prompts/list`, `prompts/get`): Reusable templates for common interactions. Prompts standardize repetitive queries and formatting tasks.

According to [`phases/13-tools-and-protocols/06-mcp-fundamentals/docs/en.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/phases/13-tools-and-protocols/06-mcp-fundamentals/docs/en.md), each primitive response includes cache control hints: `ttlMs` (time-to-live in milliseconds) and `cacheScope` (visibility level such as `"private"` or `"shared"`). This allows intelligent caching at the client or middleware layer without server-side state tracking.

### Discovery Without Handshake

Modern MCP implementations eliminate the initialization handshake entirely. The `server/discover` method provides a complete capability manifest in a single request:

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "resultType": "complete",
    "supportedVersions": ["2026-07-28"],
    "capabilities": {
      "tools": true,
      "resources": true,
      "prompts": true
    },
    "instructions": "Use tools/list, resources/list, prompts/list as needed.",
    "_meta": {
      "io.modelcontextprotocol/serverInfo": {
        "name": "notes-server",
        "version": "1.0.0"
      }
    },
    "ttlMs": 0,
    "cacheScope": "private"
  }
}

```

The `resultType: "complete"` indicates that the server has provided its full capability set. Clients can cache this response using the provided `ttlMs` and `cacheScope` directives, reducing redundant discovery calls during high-frequency interactions.

## Legacy Compatibility and Security

While modern MCP (`2026-07-28` and later) operates statelessly, the protocol maintains explicit support for legacy implementations to ensure backward compatibility without compromising modern simplicity.

### Legacy Handshake Flows

Protocols from eras `≤ 2025-11-25` require an initialization handshake and connection-scoped capabilities. As noted in the MCP documentation at [`phases/13-tools-and-protocols/06-mcp-fundamentals/docs/en.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/phases/13-tools-and-protocols/06-mcp-fundamentals/docs/en.md), MCP separates these legacy flows from the modern stateless core. Dual-era clients detect the appropriate path based on version negotiation, ensuring that stateful and stateless implementations never mix paradigms.

The `skill-mcp-handshake-tracer` artifact in `phases/13-tools-and-protocols/06-mcp-fundamentals/outputs/` demonstrates how servers audit each message independently to detect legacy handshake attempts and route them appropriately.

### Deployment Security Gates

Before exposing an MCP server to non-loopback interfaces (public networks), the protocol mandates a security checkpoint. According to [`learning-paths/model-context-protocol.json`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/learning-paths/model-context-protocol.json), Lesson 15 requires validation of:

- **Poisoned metadata detection**: Ensuring `_meta` objects haven't been tampered with in transit
- **Routing validation**: Verifying that requests route to intended endpoints only
- **Authorization scopes**: Confirming that client capabilities align with permitted operations

These gates prevent unauthorized access and ensure that stateless requests cannot be replayed or redirected maliciously.

## Implementation Reference

The reference implementation in [`phases/13-tools-and-protocols/06-mcp-fundamentals/code/main.py`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/phases/13-tools-and-protocols/06-mcp-fundamentals/code/main.py) demonstrates a complete stateless MCP server and client in Python. This implementation handles version negotiation, primitive discovery, and metadata validation without maintaining connection state between requests.

Key implementation details from the source:

- **Request parsing**: Extract `_meta` from `params` and validate protocol version before method dispatch
- **Method routing**: Route `tools/list`, `resources/read`, and other primitives based on capability flags
- **Error handling**: Return structured `-32022` errors for version mismatches with supported version lists
- **Caching layer**: Respect `ttlMs` and `cacheScope` in responses to enable client-side optimization

## Summary

- **Stateless by design**: MCP embeds all context in per-request `_meta` objects, eliminating session management overhead and enabling horizontal scaling.
- **Three core primitives**: Tools (actions), Resources (data), and Prompts (templates) provide a complete interface for AI agents to interact with external systems.
- **Explicit versioning**: Protocol version `2026-07-28` introduces modern stateless operation, while error code `-32022` enables graceful degradation when versions mismatch.
- **Zero-handshake discovery**: The `server/discover` method provides immediate capability inspection without initialization ceremonies, reducing latency for AI workflows.
- **Security-first deployment**: Non-loopback exposure requires validation gates for metadata integrity, routing, and authorization as defined in the MCP learning path.

## Frequently Asked Questions

### How does MCP differ from traditional REST APIs?

Unlike REST APIs that typically require authentication handshakes and maintain session state via cookies or tokens, MCP is completely stateless. Each JSON-RPC request carries complete protocol version, capabilities, and identity metadata in the `_meta` object, allowing servers to process requests independently without connection history. This design makes MCP servers more resilient to failures and easier to scale horizontally compared to traditional REST architectures.

### What is the difference between modern and legacy MCP protocol versions?

Modern MCP versions starting with `2026-07-28` operate without initialization handshakes, using only per-request metadata for context. Legacy versions from eras `≤ 2025-11-25` require connection-scoped state and explicit initialization flows. Modern servers detect legacy clients through version strings provided in the `_meta` object and can respond appropriately, while dual-era clients automatically select the correct communication pattern based on `server/discover` responses.

### How does version negotiation work when a client and server mismatch?

When a client sends a request with an unsupported protocol version in the `_meta` block, the server responds with JSON-RPC error code `-32022` ("Unsupported protocol version") and includes a `data` field listing all supported versions. The client can then retry the request using a compatible version from that list. This explicit negotiation prevents silent protocol failures and ensures deterministic behavior across heterogeneous AI agent ecosystems.

### What security measures are required before deploying an MCP server publicly?

Before exposing an MCP server on non-loopback interfaces, the protocol requires completing Lesson 15 security gates as defined in [`learning-paths/model-context-protocol.json`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/learning-paths/model-context-protocol.json). These gates validate that metadata hasn't been poisoned, routing paths are secure, and client authorization scopes are properly enforced. These requirements ensure that stateless requests—which carry all authentication context in the `_meta` object—cannot be intercepted, replayed, or redirected to unauthorized endpoints.