What Is the Model Context Protocol (MCP) in AI?
The Model Context Protocol (MCP) is a JSON-RPC 2.0-based open standard that unifies how large language models (LLMs) discover and invoke external tools, read resources, and execute reusable prompts, eliminating vendor-specific integration fragmentation.
The Model Context Protocol (MCP) has emerged as the de-facto standard for exposing capabilities to AI systems. According to the rohitg00/ai-engineering-from-scratch curriculum, MCP solves the pre-2025 integration chaos where developers rewrote the same connectors for Anthropic, OpenAI, and Google by defining a single, provider-agnostic specification.
Core Primitives of the Model Context Protocol
MCP defines three fundamental primitives that servers expose to clients. This architecture is documented in phases/11-llm-engineering/14-model-context-protocol/docs/en.md.
Tools
Tools represent callable functions that perform computations or side effects. Each tool exposes a JSON schema defining its input arguments, a human-readable description, and optional metadata such as destructiveHint to flag potentially dangerous operations. The host discovers available tools via the tools/list method and invokes them using tools/call.
Resources
Resources provide read-only data addressed by URI schemes (e.g., config://app, file://docs). Unlike tools, resources are passive data sources that the client reads via resources/read without triggering computations. This pattern enables LLMs to ingest context such as database rows, API responses, or configuration files.
Prompts
Prompts are templated, reusable prompt strings that servers expose as shortcuts. Clients retrieve these via prompts/get and prompts/list, allowing centralized management of complex system prompts for tasks like code review or data analysis.
MCP Architecture and Handshake
Capability Negotiation
Every MCP session begins with an initialize handshake. The client advertises its supported capabilities, and the server responds with its protocol version and available primitives (tools, resources, prompts, plus optional logging and roots). This negotiation enables fine-grained permission control where hosts request only required capabilities.
Transport Layer Options
The protocol supports three transport mechanisms as implemented in phases/11-llm-engineering/14-model-context-protocol/code/main.py:
- stdio: Standard input/output for local development and simple subprocess communication
- WebSocket: Bidirectional streaming for persistent connections
- Streamable HTTP: A stateless, POST-based endpoint with optional Server-Sent Events (SSE) for streaming, introduced in the 2025-06-18 spec revision as the default for production deployments
Building an MCP Server: Practical Implementation
The following implementation from phases/11-llm-engineering/14-model-context-protocol/code/main.py demonstrates a minimal MCP server using the FastMCP framework:
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("demo-server")
@mcp.tool()
def add(a: int, b: int) -> int:
"""Add two integers."""
return a + b
@mcp.resource("config://app")
def app_config() -> str:
"""Return the app's current JSON config."""
return '{"env":"prod","region":"us-east-1"}'
@mcp.prompt()
def code_review(language: str, code: str) -> str:
"""Review code for correctness and style."""
return f"You are a senior {language} reviewer. Review:\n\n{code}"
if __name__ == "__main__":
mcp.run(transport="stdio")
Type hints on the server automatically generate JSON Schema definitions, eliminating manual schema duplication across LLM providers.
In-Process Client Example
For testing or embedded scenarios, you can interact with the server without external dependencies:
client = MCPClient(server) # server is the MCPServer instance above
init = client.request("initialize", {"protocolVersion": PROTOCOL_VERSION})
print(f"Connected to {init['serverInfo']['name']}")
tools = client.request("tools/list")["tools"]
print(f"Discovered tools: {[t['name'] for t in tools]}")
result = client.request("tools/call", {"name": "add", "arguments": {"a": 40, "b": 2}})
print("add(40,2) →", result["content"][0]["text"])
Production Deployment with Streamable HTTP
For remote, horizontally scalable deployments behind load balancers, use the Streamable HTTP transport:
# Server entrypoint
mcp.run(transport="streamable-http", host="0.0.0.0", port=8765)
Configure the host client (Claude Desktop, Claude Code, etc.) with:
{
"mcpServers": {
"demo": {
"type": "http",
"url": "https://tools.example.com/mcp"
}
}
}
Security and Safety Mechanisms
The Model Context Protocol enforces three mandatory safety patterns detailed in phases/11-llm-engineering/14-model-context-protocol/docs/en.md:
- Allow-lists: Servers must declare explicit file-system roots and URI schemes they can access
- Human-in-the-loop: Tools marked with
destructiveHintrequire explicit user confirmation before execution - Tool-poisoning defenses: Clients must treat resource content as untrusted, preventing prompt injection attacks through external data
MCP Ecosystem and Adoption
By early 2026, major LLM vendors including Anthropic, OpenAI, and Google ship MCP-compatible clients. IDE extensions and agent frameworks (Claude Code, Cursor, Amp, OpenCode) consume MCP servers out-of-the-box, enabling a single server implementation to serve multiple hosts. For production-grade deployments involving OAuth 2.1 and policy enforcement, refer to phases/19-capstone-projects/13-mcp-server-with-registry/docs/en.md.
Summary
- MCP is a JSON-RPC 2.0 protocol standardizing LLM tool integration across vendors
- Three primitives (Tools, Resources, Prompts) provide a complete interface for computation, data, and templating
- Automatic schema generation from type hints eliminates manual JSON Schema maintenance
- Flexible transports (stdio, WebSocket, Streamable HTTP) support both development and production deployments
- Built-in safety mechanisms include allow-lists, destructive hints, and content sanitization
Frequently Asked Questions
What is the difference between MCP and traditional function calling?
Traditional function calling requires vendor-specific JSON schemas and endpoints for each LLM provider. MCP provides a unified JSON-RPC 2.0 interface where a single server implementation works across Anthropic, OpenAI, Google, and other hosts, reducing integration code by standardizing discovery via tools/list and invocation via tools/call.
How does MCP handle authentication for external APIs?
The base MCP specification defines the transport and message format, while authentication is handled at the transport layer or via server-side implementation. The capstone project in phases/19-capstone-projects/13-mcp-server-with-registry/docs/en.md demonstrates production patterns using OAuth 2.1 and OPA policies to secure tool endpoints.
Which transport should I use for production MCP servers?
Use Streamable HTTP for production deployments. Unlike stdio (which requires local process spawning) or WebSocket (which maintains persistent connections), Streamable HTTP operates over stateless POST requests that scale horizontally behind standard load balancers and support Server-Sent Events for streaming responses.
Can MCP servers expose dynamic resource content?
Yes. While resources are addressed by static URIs (e.g., config://app), the server implementation can return dynamic content on each resources/read call. This allows real-time data such as database query results or API responses to flow into the LLM context without requiring tool invocation.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →