Executive Summary
- MCP standardizes LLM-to-tool communication using open JSON-RPC 2.0 primitives.
- The protocol defines three core capabilities: Tools (executable actions), Resources (readable data), and Prompts (reusable templates).
- Transports operate over standard input/output (stdio) for local tools or Server-Sent Events (SSE) for remote servers.
- Clean protocol separation isolates host applications from third-party tool implementation details.
- Security boundaries require client-side confirmation gates before executing mutating tools.
Why the ecosystem needed the Model Context Protocol
Before the Model Context Protocol (MCP) emerged, connecting language models to external tools was an engineering mess. Every AI framework (LangChain, LlamaIndex, AutoGen, custom scripts) invented its own ad-hoc tool definition format.
If a developer built a Postgres query tool for Claude, they had to rewrite it completely to work with OpenAI, and rewrite it again to integrate into an IDE extension. This fragmentation created massive integration debt across the software industry.
MCP solves this by establishing an open, standardized client-server protocol. An MCP server exposes tools, data resources, and prompt templates once; any MCP-compliant client (whether an IDE, desktop assistant, or cloud agent) can connect to it seamlessly over standard JSON-RPC.
The USB-C of AI interfaces
MCP does for AI tool connectivity what USB-C did for hardware peripherals: standardizes the physical and protocol interface so any host can connect to any device without custom adapters.
The three core MCP primitives: Tools, Resources, Prompts
The MCP specification is built around three foundational server capabilities:
1. Tools: Functions that an LLM can invoke to perform computation or execute side effects (e.g. `execute_sql`, `git_commit`). Tools take structured parameters defined by JSON Schema and return structured content blocks.
2. Resources: Read-only data sources that can be attached to context (e.g. `file:///var/log/app.log`, `postgres://db/users/schema`). Resources are identified by URIs and support dynamic subscription notifications when data changes.
3. Prompts: Parameterized prompt templates exposed by the server (e.g. `analyze_codebase_diff`), allowing domain experts to curate optimal reasoning scaffolding directly alongside the data source.
The three MCP protocol primitives compared
| Feature | Primitive | Primary Purpose | Mutation Risk | Invocation Model |
|---|---|---|---|---|
| Tools | Execute code, query APIs, modify data | High (Requires permission checks) | Model-driven tool calling (`tools/call`) | |
| Resources | Provide static or streaming context data | Zero (Read-only observation) | Application/User attached (`resources/read`) | |
| Prompts | Provide structured reasoning workflows | Zero (Template generation) | User/Workflow initiated (`prompts/get`) |
JSON-RPC 2.0 wire format & protocol framing
MCP uses standard JSON-RPC 2.0 for all message exchanges. Every interaction consists of a structured Request object and a corresponding Response object.
When an MCP client connects, it issues an `initialize` request to negotiate capabilities (such as tools, resources, and logging). Once initialized, the client can query available tools using `tools/list` and execute specific functions using `tools/call`.
Because JSON-RPC is text-based and language-agnostic, MCP servers can be implemented in Python, TypeScript, Go, Rust, or C++ with zero framework lock-in.
TypeScript MCP server implementation pattern
The code below demonstrates a production-grade MCP server implemented using the official TypeScript SDK.
Transport architectures: stdio vs Server-Sent Events (SSE)
MCP supports two primary transport mechanisms depending on the deployment topology:
1. Standard I/O (stdio): Used when the MCP server runs as a local child process spawned by the client (e.g. an IDE running a local git or file tool). stdio provides zero-latency IPC with zero network exposure.
2. Server-Sent Events (SSE) over HTTP: Used when the MCP server runs on a remote server or in a shared Kubernetes cluster. The client sends JSON-RPC requests via HTTP POST and receives streaming responses via an open SSE connection.
Security boundaries and client-side confirmation gates
Because MCP tools can execute arbitrary code or query internal databases, security is paramount. The MCP architecture enforces strict separation of concerns.
The MCP server is responsible for parameter schema validation and execution isolation (e.g. running queries against read-only replicas).
The MCP client (the host application) is responsible for user authorization and confirmation gates. If a tool is flagged as mutating (e.g. `delete_branch`), the client must display an explicit confirmation dialog to the human operator before dispatching the JSON-RPC request.
MCP server development checklist
Verify these architectural and security requirements before deploying MCP servers.
MCP server deployment checklist
1Protocol & Typing
- Server exposes standard JSON-RPC 2.0 capabilities during initialize
- Tool parameters are rigorously typed using standard JSON Schema
- Tool descriptions provide clear natural language context for LLM selection
2Transport & Performance
- stdio transport is used for local zero-latency developer tooling
- SSE transport implements proper connection keep-alives and reconnection
- Large resource payloads support streaming and pagination
3Security & Permissions
- Mutating tools require explicit human approval gates in the client UI
- SQL tools execute against unprivileged, read-only database replicas
- Outbound network egress is restricted to whitelisted API endpoints