top of page
DevCollar Private Limited Logo

MCP Explained: How Model Context Protocol Actually Works

Writer: Devesh Singh
Devesh Singh
Aug 17
14 min read

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.

How Model Context Protocol (MCP) works, showing the request flow from an AI application through an MCP client and server to external tools and data

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.

  1. Think of MCP as an integration boundary, not an AI framework.

    Its purpose is to standardize communication between AI applications and external capabilities.

  2. Keep tools narrow.

    Small, well-defined capabilities are easier for models to select and easier for applications to secure.

  3. Treat tool descriptions as API design.

    The model needs enough information to understand when a tool should be used.

  4. Separate MCP from business logic.

    MCP handlers should call application services rather than becoming the application itself.

  5. 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.

  6. Use resources when the model needs information and tools when it needs actions.

    Don't turn every piece of context into a function call.

  7. Design for stateless infrastructure.

    The modern MCP protocol makes horizontally scalable server architectures much easier.

  8. Make important state explicit.

    If workflows need state across requests, use IDs or handles rather than depending on hidden transport sessions.

  9. Instrument tool execution.

    AI systems become extremely difficult to debug without traces showing exactly which capabilities were invoked.

  10. 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

Rated 0 out of 5 stars.
No ratings yet

Add a rating

Join the DC Club

Join our email list and get access to specials deals exclusive to our subscribers.

Thanks for submitting!

© 2026

 by DevCollar Private Limited

bottom of page