MCP Explained: How Model Context Protocol Actually Works
Large language models are powerful when the information they need already exists inside their context.
But real applications rarely work that way.
An AI assistant might need to:
search internal documentation,
query a database,
read files,
inspect a GitHub repository,
check an order,
retrieve analytics,
create a support ticket,
interact with an internal API,
or trigger an external service.
The moment an AI system needs to interact with the outside world, we encounter a much larger engineering problem:
How should AI applications discover and interact with external tools and data in a consistent way?
Without a standard, every integration becomes custom.
AI Application
│
├── Custom GitHub integration
├── Custom database integration
├── Custom filesystem integration
├── Custom analytics integration
├── Custom CRM integration
└── Custom internal API integration
Now imagine multiple AI applications needing access to those same systems.
The number of integrations grows quickly.
This is the problem the Model Context Protocol — MCP — is designed to address.
MCP defines a standard protocol through which AI applications can discover and interact with tools, resources, prompts, and other capabilities exposed by external systems. The current MCP architecture uses a client-server model and a JSON-RPC-based data layer, while keeping the protocol itself independent of how an application actually uses its LLM.
But understanding MCP requires going deeper than:
"It's USB-C for AI."
That analogy is useful, but it hides the interesting engineering.
Let's look at what actually happens when an AI application connects to an MCP server.
The Problem MCP Is Trying to Solve
Imagine we are building an AI engineering assistant.
We want it to access:
GitHub
Jira
PostgreSQL
Google Drive
Internal APIs
Monitoring
Documentation
Without MCP, we might implement:
AI Assistant
│
┌──────────────┼──────────────┐
▼ ▼ ▼
GitHub Code Jira Code DB Code
│ │ │
▼ ▼ ▼
GitHub API Jira API PostgreSQL
Every integration has its own:
Authentication
API format
Tool definition
Error handling
Discovery
Schemas
Connection logic
Now suppose another AI application needs the same integrations.
We build them again.
AI Application A
/ | \
/ | \
GitHub Jira DB
AI Application B
/ | \
/ | \
GitHub Jira DB
This starts becoming an M × N integration problem.
If we have:
M AI applications
×
N external systems
we potentially create:
M × N custom integrations
MCP introduces a common boundary.
AI Applications
│
│
MCP
│
┌──────────┼──────────┐
▼ ▼ ▼
GitHub Jira Database
MCP MCP MCP
Server Server Server
Now AI applications understand one protocol.
External systems expose capabilities through that protocol.
MCP Is a Protocol, Not an AI Model
This distinction is important.
MCP does not:
train an AI model,
make the model smarter,
provide reasoning,
replace an LLM,
decide what an agent should do.
MCP focuses on context exchange between applications. The official specification explicitly separates MCP from how AI applications manage or use their language models.
Think of the architecture as:
User
│
▼
AI Application
│
▼
LLM
│
decides it needs
information
│
▼
MCP Client
│
▼
MCP Server
│
▼
External System
MCP lives in the integration layer.
It provides a common language for AI applications and external capabilities.
The Three Important Participants
The MCP architecture defines three participants:
MCP Host
MCP Client
MCP Server
They sound similar, but their responsibilities are different.
1. MCP Host
The host is the AI application.
Conceptually:
┌───────────────────────────┐
│ AI Application │
│ │
│ Chat UI │
│ LLM orchestration │
│ Permissions │
│ Tool decisions │
│ Context management │
│ │
│ MCP Host │
└───────────────────────────┘The host coordinates the overall experience.
It decides things like:
Which servers are available?
Which tools can the model see?
Which results enter the context?
Does an action require confirmation?
Which user permissions apply?
2. MCP Client
Inside the host are MCP clients.
Typically, there is one MCP client corresponding to each MCP server connection.
For example:
AI Host
│
┌──────────┼──────────┐
▼ ▼ ▼
MCP Client MCP Client MCP Client
A B C
│ │ │
▼ ▼ ▼
GitHub Files Database
MCP MCP MCP
Server Server Server
The client handles protocol communication with its server.
The LLM generally shouldn't need to care whether the server is local, remote, implemented in TypeScript, Python, Go, or something else.
3. MCP Server
The MCP server exposes capabilities.
For example, a database MCP server could expose:
Database MCP Server
│
├── inspect_schema
├── query_database
├── describe_table
└── resources containing schema information
A project-management MCP server might expose:
Project MCP Server
│
├── search_tasks
├── get_task
├── create_task
└── update_task
The server becomes an adapter between MCP and the underlying system.
MCP
↓
MCP Server
↓
Application Service
↓
Database / API / SaaS
This separation is extremely useful.
Your business logic does not need to become MCP-specific.
MCP Has Two Layers
Underneath the client-server architecture, MCP separates communication into two major layers:
┌──────────────────────────────┐
│ Data Layer │
│ │
│ JSON-RPC │
│ Tools │
│ Resources │
│ Prompts │
│ Discovery │
│ Notifications │
└──────────────────────────────┘
│
▼
┌──────────────────────────────┐
│ Transport Layer │
│ │
│ STDIO │
│ Streamable HTTP │
│ Authentication │
│ Message transport │
└──────────────────────────────┘The data layer defines what the messages mean.
The transport layer defines how those messages travel.
MCP's current specification uses JSON-RPC 2.0 for its data-layer message structure and supports STDIO and Streamable HTTP as its primary transports.
That separation means the same basic protocol concepts can work whether the MCP server is running:
on your laptop
or
on infrastructure thousands of kilometers away
The Three Core MCP Primitives
The easiest way to understand what an MCP server can provide is through its three main server-side primitives:
Tools
Resources
Prompts
The distinction between them matters.
Tools: Things the AI Can Do
A tool represents an executable capability.
Examples:
search_orders
create_ticket
query_database
send_message
get_weather
create_invoice
Conceptually, a tool definition might look like:
{
"name": "get_order",
"description": "Retrieve an order using its order ID",
"inputSchema": {
"type": "object",
"properties": {
"orderId": {
"type": "string"
}
},
"required": ["orderId"]
}
}
This tells the client:
Tool name
↓
What it does
↓
What arguments it expects
The AI application can then expose that capability to the model.
Resources: Things the AI Can Read
Resources are different.
A resource represents contextual information.
Examples might include:
File contents
Database records
Documentation
Configuration
Repository information
Application state
Conceptually:
resource://company/refund-policy
resource://database/schema
resource://project/architecture
Resources are useful when the system needs to provide information, rather than perform an operation.
Think:
Tool
→ Do something
Resource
→ Read something
That distinction also helps us think about security.
Reading a document and deleting a customer account should not have identical permission models.
Prompts: Reusable Interaction Templates
MCP servers can also expose prompts.
Prompts provide reusable templates for model interactions.
For example:
review_pull_request
summarize_incident
analyze_database_schema
prepare_customer_response
A prompt might combine:
Instructions
+
Expected workflow
+
Examples
+
Arguments
into a reusable interaction pattern.
The application can discover these templates instead of hardcoding every workflow independently.
Discovery Is One of MCP's Most Important Ideas
Imagine connecting an AI application to an MCP server that it has never seen before.
How does it know what the server can do?
Hardcoding this defeats the purpose.
Instead, MCP supports discovery.
The client can ask:
What do you support?
and:
What tools are available?
For example:
MCP Client
│
│ tools/list
▼
MCP Server
│
▼
Available Tools
The server might return:
search_customers
get_customer
get_orders
create_support_ticket
Now the AI application knows what capabilities exist.
The current protocol also provides server/discover, through which clients can discover supported protocol versions, server identity and capabilities.
This makes MCP integrations self-describing.

What Happens When the User Makes a Request?
Suppose the user asks:
What happened with order 4821?
Let's follow the request.
User
│
▼
"What happened with order 4821?"
│
▼
AI Application
│
▼
LLM
The model sees that a tool exists:
get_order(orderId)
It determines that additional information is needed.
So it proposes:
{
"tool": "get_order",
"arguments": {
"orderId": "4821"
}
}
The application then handles execution through MCP.
LLM
│
│ requests get_order
▼
MCP Client
│
│ tools/call
▼
MCP Server
│
▼
Order Service
│
▼
Database
The database might return:
{
"orderId": "4821",
"status": "delayed",
"expectedDelivery": "2026-08-19"
}
That result travels back:
Database
↓
Order Service
↓
MCP Server
↓
MCP Client
↓
AI Application
↓
LLM
The model can now answer:
Order 4821 is currently delayed and is expected to arrive on August 19.
That is the fundamental MCP tool loop.
MCP Does Not Mean the Model Executes Code Directly
This distinction is extremely important.
The model does not necessarily receive:
Database credentials
Shell access
API credentials
Filesystem access
Instead:
LLM
│
│ proposes tool call
▼
Application
│
│ validates
▼
MCP Client
│
▼
MCP Server
│
│ applies authorization
▼
Service
This creates security boundaries.
The model says:
I would like to call get_order.
The application decides whether that should actually happen.
Tools Should Be Narrow
Suppose we expose:
execute_database_command(command)
That gives the model enormous freedom.
A safer architecture might expose:
get_customer
search_orders
get_order_status
create_refund_request
Now:
Broad capability
↓
Large risk surface
Narrow capability
↓
Smaller risk surface
This also improves model behavior.
A tool called:
create_refund_request
has clearer intent than:
execute_operation
Tool design is therefore partly API design for AI systems.
Tool Descriptions Are Part of Your Interface
Traditional APIs are primarily consumed by developers.
MCP tools may be selected by models.
That means descriptions matter.
Poor:
get_data
"Gets data."
Better:
get_order
"Retrieve the current status and details of an order
using its unique order ID. Use this when the user
asks about a specific existing order."
The model now has more information for deciding:
Should I call this tool?
Tool naming and descriptions can directly influence agent reliability.
MCP Is Now Stateless at the Protocol Core
This is one area where MCP changed significantly.
Many older MCP tutorials describe a handshake followed by a persistent protocol-level session.
That mental model is outdated for the current 2026-07-28 specification.
The current MCP core is stateless. Requests carry the protocol version and relevant client capabilities in metadata so that the server can process each request independently.
Previously, infrastructure could look more like:
Client
│
▼
Server A
│
│ session state
│
▼
Server A
That creates challenges when scaling.
You might need:
Sticky sessions
Shared session storage
Persistent connections
Session-aware routing
With the stateless core:
Load Balancer
/ | \
▼ ▼ ▼
Server A Server B Server C
Any appropriately configured server instance can process the request.
That makes MCP much easier to deploy using conventional cloud infrastructure.
The July 2026 specification specifically introduced this stateless protocol core to improve reliability and scalability.
Stateless Protocol Does Not Mean Stateless Applications
This distinction is subtle but important.
Imagine an MCP tool starts a long-running data-processing operation.
The application still needs state.
Instead of hiding that state inside the transport session, the tool can return a handle.
start_analysis()
↓
analysis_id = "job_4821"
Then another call can use:
get_analysis_status(
analysis_id = "job_4821"
)
The state becomes explicit.
Protocol
→ Stateless
Application
→ Can still maintain state
The current MCP design explicitly supports this pattern; the July 2026 changes removed protocol-level sessions without requiring applications themselves to become stateless.
Local vs Remote MCP Servers
Not every MCP server needs to run on the internet.
MCP supports both local and remote server patterns.
Local MCP Server
A local server may communicate through standard input/output.
AI Application
│
│ STDIO
▼
Local MCP Server
│
▼
Local Files
This can be useful for:
Filesystem access
Developer tools
Local databases
CLI utilities
Local automation
There is no network request required between the client and server process.
Remote MCP Server
A remote server can communicate through Streamable HTTP.
AI Application
│
│ HTTPS
▼
Remote MCP Server
│
▼
Cloud Service
This works well for:
SaaS integrations
Enterprise APIs
Cloud databases
Shared organizational tools
Remote business systems
The same underlying MCP concepts can apply to both.
MCP Does Not Replace REST APIs
This is another common misconception.
Suppose our backend already exposes:
GET /customers/:id
GET /orders/:id
POST /refunds
GET /analytics
Should we delete these and replace everything with MCP?
Usually, no.
Instead:
Business Logic
│
┌───────────┴───────────┐
▼ ▼
REST API MCP Server
│ │
▼ ▼
Web / Mobile Apps AI Applications
Both interfaces can call the same application services.
For example:
OrderService
│
┌─────────┴─────────┐
▼ ▼
REST Route MCP Tool
│ │
└─────────┬─────────┘
▼
Database
This is an important architectural boundary.
MCP should expose your system to AI.
It should not force you to rebuild your system around AI.
MCP vs Function Calling
Another question developers often ask is:
Isn't MCP just function calling?
They are related, but they operate at different layers.
Function calling might look like:
LLM
↓
Functions configured
inside one application
MCP adds a standardized integration layer:
LLM
↓
AI Application
↓
MCP Client
↓
External MCP Server
↓
Tools / Resources / Prompts
Function calling answers:
How can the model request a function?
MCP addresses a broader problem:
How can applications discover and communicate with external capability providers through a standard protocol?
An MCP host may ultimately translate an MCP tool definition into whatever tool/function interface its chosen model provider understands.
Authorization Still Matters
Imagine an MCP server exposes:
get_invoice
create_invoice
cancel_invoice
refund_payment
These operations clearly have different risk levels.
A secure architecture might look like:
Tool Request
↓
Authentication
↓
Authorization
↓
Input Validation
↓
Business Rules
↓
Risk Check
↓
Execution
For sensitive operations:
refund_payment
↓
Check user permission
↓
Check refund amount
↓
Require confirmation
↓
Execute
MCP standardizes communication.
It does not mean:
Model requested it
=
Model is authorized
The current specification continues to evolve its authorization model and introduced additional authorization hardening in the July 2026 release.
Human-in-the-Loop Matters
Suppose the agent wants to:
Read customer
Automatic execution may be acceptable.
Now suppose it wants to:
Delete customer
Different story.
A useful architecture categorizes tools.
Tool Request
│
┌───────┴───────┐
▼ ▼
Read-only Mutating
│ │
▼ ▼
Execute Risk check
│
┌────────┴────────┐
▼ ▼
Low Risk High Risk
│ │
▼ ▼
Execute Human approval
│
▼
Execute
MCP's elicitation capability can also support flows where servers need additional user information or confirmation, with the current specification delivering these interactions through Multi Round-Trip Requests.
What Are Multi Round-Trip Requests?
Statelessness creates an interesting problem.
Suppose a tool starts processing:
refund_order
but discovers that confirmation is required.
The server needs to ask:
Are you sure you want to refund ₹8,000?
Previously, this type of server-to-client interaction could depend more heavily on persistent bidirectional communication.
The current MCP specification introduces Multi Round-Trip Requests — MRTR for this pattern.
Conceptually:
Client
│
│ refund_order
▼
Server
│
│ input_required
▼
Client
│
│ asks user
▼
User confirms
│
▼
Client retries original request
with confirmation
│
▼
Server
│
▼
Refund
This preserves the stateless core while still allowing richer workflows.
MCP Can Support Long-Running Operations
Some operations cannot finish during a normal request.
For example:
Analyze 100,000 documents
Generate a large report
Process a repository
Run a migration
Perform a complex investigation
The modern MCP ecosystem includes a Tasks extension for durable long-running work. A server can return a handle that clients use to inspect status and retrieve results later.
Conceptually:
Start Task
↓
task_id
↓
Processing...
↓
Check Status
↓
Processing...
↓
Check Status
↓
Complete
↓
Retrieve Result
This is much healthier than keeping an HTTP connection open indefinitely.
MCP Changes the Integration Architecture
Before MCP:
AI Application
│
├── GitHub-specific integration code
│
├── Database-specific integration code
│
├── Jira-specific integration code
│
└── Filesystem-specific integration code
With MCP:
AI Application
│
▼
MCP Layer
│
┌──────────────┼──────────────┐
▼ ▼ ▼
GitHub MCP Database MCP Jira MCP
Server Server Server
│ │ │
▼ ▼ ▼
GitHub PostgreSQL Jira
The integration contract becomes reusable.
That doesn't eliminate complexity.
It moves complexity behind a standardized boundary.
MCP and AI Agents
This becomes particularly interesting when building agents.
Imagine an engineering agent connected to:
GitHub MCP
Database MCP
Monitoring MCP
Project Management MCP
Documentation MCP
The agent might receive:
Investigate why checkout errors increased after yesterday's deployment.
The workflow could become:
User Request
↓
Agent
↓
Monitoring Tool
↓
Identify error spike
↓
GitHub Tool
↓
Inspect deployment changes
↓
Documentation Resource
↓
Understand expected behavior
↓
Database Tool
↓
Inspect affected records
↓
Agent Reasoning
↓
Explanation
MCP isn't performing the reasoning.
The agent is.
MCP gives the agent a standardized way to reach the systems required for that reasoning.
MCP Does Not Automatically Make an Agent Good
Connecting 100 tools to a model does not necessarily create a capable agent.
It may actually make the system worse.
More Tools
↓
More Choices
↓
More Context
↓
More Potential Confusion
Tool design still matters.
A production system should think carefully about:
Which tools does this agent actually need?
Which tools should this user be allowed to invoke?
Which descriptions make selection clear?
Which results should enter the context?
Which actions need approval?
MCP solves interoperability.
It does not solve agent architecture.
A Production MCP Architecture
A mature architecture might look like:
User
│
▼
AI Application
│
┌──────┴──────┐
▼ ▼
LLM Layer Policy Layer
│ │
└──────┬──────┘
▼
MCP Host
│
┌─────────────┼─────────────┐
▼ ▼ ▼
MCP Client MCP Client MCP Client
│ │ │
▼ ▼ ▼
GitHub MCP Data MCP Support MCP
Server Server Server
│ │ │
▼ ▼ ▼
GitHub PostgreSQL CRM/API
Around that architecture, we still need:
Authentication
Authorization
Validation
Observability
Rate limiting
Audit logs
Human approval
Timeouts
Retries
Error handling
MCP does not remove normal production engineering.
If anything, allowing AI systems to perform real actions makes those engineering boundaries more important.
Observability Is Critical
Suppose a user reports:
The agent changed the wrong ticket.
You need to reconstruct:
What did the user ask?
What did the model decide?
Which tool did it choose?
What arguments did it send?
Which MCP server handled it?
What did the server return?
What happened afterward?
A useful trace might look like:
Agent Run: 82941
│
├── Tool: search_tickets
│ └── 143 ms
│
├── Tool: get_ticket
│ └── 81 ms
│
└── Tool: update_ticket
└── 219 ms
MCP should participate in your application's observability strategy.
The current specification has also moved structured observability toward standard approaches such as OpenTelemetry rather than treating protocol-specific logging as the long-term solution.
The Architecture We Prefer
The cleanest mental model is:
┌──────────────────────────────────┐
│ AI Experience │
│ │
│ Chat / Agent / IDE / Automation │
└────────────────┬─────────────────┘
│
▼
┌──────────────────────────────────┐
│ AI Orchestration │
│ │
│ LLM │
│ Reasoning │
│ Context │
│ Permissions │
└────────────────┬─────────────────┘
│
▼
┌──────────────────────────────────┐
│ MCP Layer │
│ │
│ Discovery │
│ Tools │
│ Resources │
│ Prompts │
│ Transport │
└────────────────┬─────────────────┘
│
▼
┌──────────────────────────────────┐
│ Application Services │
│ │
│ Orders │
│ Customers │
│ Search │
│ Analytics │
│ Documents │
└────────────────┬─────────────────┘
│
▼
┌──────────────────────────────────┐
│ Infrastructure │
│ │
│ Databases │
│ APIs │
│ Files │
│ SaaS Platforms │
└──────────────────────────────────┘Each layer has a responsibility.
The LLM reasons.
The host orchestrates.
MCP standardizes communication.
Application services enforce business logic.
Infrastructure stores and processes the real data.
That separation is what makes the architecture maintainable.
Common MCP Misconceptions
Before finishing, there are several misconceptions worth clearing up.
"MCP replaces APIs."
No.
MCP can sit on top of existing application services and APIs.
"MCP is an AI agent."
No.
Agents can use MCP.
MCP itself is a protocol.
"MCP gives the model direct access to my database."
It shouldn't.
Expose narrow, authorized capabilities through a server.
"Everything should become an MCP tool."
No.
Resources and prompts exist for different purposes, and many internal operations don't need to be exposed to AI at all.
"MCP makes actions safe."
No.
Authentication, authorization, validation, business rules, confirmations and audit logging remain your responsibility.
"MCP servers must maintain sessions."
Not in the current protocol core.
MCP 2026-07-28 is stateless, although applications can still explicitly maintain state when their workflows require it.
Lessons for Developers
Working with MCP becomes much easier once several principles are clear.
Think of MCP as an integration boundary, not an AI framework.
Its purpose is to standardize communication between AI applications and external capabilities.
Keep tools narrow.
Small, well-defined capabilities are easier for models to select and easier for applications to secure.
Treat tool descriptions as API design.
The model needs enough information to understand when a tool should be used.
Separate MCP from business logic.
MCP handlers should call application services rather than becoming the application itself.
Never confuse tool availability with authorization.
A model knowing that an operation exists does not mean the current user should be allowed to execute it.
Use resources when the model needs information and tools when it needs actions.
Don't turn every piece of context into a function call.
Design for stateless infrastructure.
The modern MCP protocol makes horizontally scalable server architectures much easier.
Make important state explicit.
If workflows need state across requests, use IDs or handles rather than depending on hidden transport sessions.
Instrument tool execution.
AI systems become extremely difficult to debug without traces showing exactly which capabilities were invoked.
Don't expose everything simply because MCP makes it possible.
The best agent often has the smallest useful set of capabilities.
Final Thoughts
MCP becomes much less mysterious once you stop thinking about it as something happening inside the AI model.
It is an architectural boundary.
User Intent
↓
LLM Reasoning
↓
AI Application
↓
MCP Client
↓
MCP Server
↓
Application Service
↓
Real System
The LLM determines what it needs.
The AI application controls the workflow.
MCP standardizes how external capabilities are discovered and invoked.
The server controls access to the underlying system.
And your normal application architecture remains responsible for security, business rules and data integrity.
That is what makes MCP interesting.
The long-term opportunity isn't simply giving models more tools.
It is creating a standardized ecosystem where AI applications can interact with software capabilities without every developer rebuilding every integration from scratch.
As AI applications move from answering questions to performing real work, that integration layer becomes increasingly important.
And MCP is emerging as one of the key protocols defining how that layer works.



Comments