You've heard about MCP. You know it connects AI to tools. But where does it actually sit in your architecture?
Let me draw you a map.
The modern AI stack
Here's a typical AI application stack, top to bottom:
┌─────────────────────────────────────┐
│ User Interface │ ← What users see
├─────────────────────────────────────┤
│ Application │ ← Your app logic
├─────────────────────────────────────┤
│ AI Orchestration │ ← Agent/reasoning layer
├─────────────────────────────────────┤
│ AI Model API │ ← Claude, GPT, etc.
├─────────────────────────────────────┤
│ ┌─────────┐ ┌─────────┐ │
│ │ MCP │ │ RAG │ │ ← Data & tool access
│ └─────────┘ └─────────┘ │
├─────────────────────────────────────┤
│ External Systems │ ← DBs, APIs, services
└─────────────────────────────────────┘
MCP sits between your AI layer and your external systems. It's the bridge.
Layer by layer
Layer 1: User Interface
What users interact with.
- Chat interface
- Web app
- CLI
- API endpoint
- Slack bot
MCP has nothing to do with this layer.
Layer 2: Application
Your business logic.
- User authentication
- Request handling
- Response formatting
- Logging, analytics
MCP doesn't live here either.
Layer 3: AI Orchestration
Where AI decisions happen.
- ReAct loops
- Planning
- Memory management
- Multi-step reasoning
This layer uses MCP to call tools.
# Orchestration layer decides to call a tool
if agent.needs_tool("search_database"):
# MCP handles the actual call
result = mcp_client.call_tool("search_database", params)
Layer 4: AI Model API
The actual AI model.
- Claude API
- OpenAI API
- Local models
Some models (like Claude) have native MCP support. Others need an adapter.
Layer 5: MCP (This is where it lives)
MCP sits here. Between AI and external systems.
AI wants to do something
↓
MCP Client
↓
MCP Protocol (JSON-RPC over SSE/stdio)
↓
MCP Server
↓
External systems (DB, API, files, etc.)
MCP handles:
- Tool discovery
- Tool invocation
- Parameter passing
- Result returning
- Auth, streaming, errors
Layer 6: External Systems
The actual things MCP connects to.
- Databases
- REST APIs
- File systems
- Shell commands
- Third-party services
MCP doesn't care what's here. It just provides the interface.
MCP components
MCP has two sides:
┌─────────────────┐ ┌─────────────────┐
│ MCP Client │ ←─────→ │ MCP Server │
│ │ MCP │ │
│ (In your app │ Protocol│ (Exposes your │
│ or AI model) │ │ tools) │
└─────────────────┘ └─────────────────┘
MCP Client
Lives in your application or AI model.
- Connects to MCP servers
- Discovers available tools
- Makes tool calls
- Handles responses
Claude has a built-in MCP client. Or you use a library.
MCP Server
Exposes your tools to AI.
- Defines available tools
- Handles tool calls
- Executes against external systems
- Returns results
This is what Gantz RUn gives you — an easy way to run MCP servers.
Where MCP doesn't fit
MCP is NOT:
Not an AI model
MCP doesn't do AI. It connects AI to tools.
Wrong: "MCP will answer my questions"
Right: "MCP lets AI access my database to answer questions"
Not an orchestration framework
MCP doesn't decide what to do. That's your agent/orchestration layer.
Wrong: "MCP will figure out which tools to use"
Right: "AI decides which tools to use, MCP handles the call"
Not a RAG system
MCP is for actions. RAG is for knowledge retrieval.
Wrong: "MCP will search my documents"
Right: "MCP calls a search tool, which might use RAG"
Not your application logic
MCP just connects. Your app logic lives elsewhere.
Wrong: "MCP handles user authentication"
Right: "MCP calls a tool that checks authentication"
Integration patterns
Pattern 1: Direct integration
AI model with native MCP support.
┌──────────┐ ┌──────────────┐
│ Claude │─────→│ MCP Server │
│ (MCP │ MCP │ (Gantz) │
│ Client) │ │ │
└──────────┘ └──────────────┘
response = claude.messages.create(
messages=[...],
mcp_servers=[{
"type": "url",
"url": "https://my-tunnel.gantz.run/sse",
"name": "tools"
}],
tools=[{"type": "mcp_toolset"}]
)
Pattern 2: Through orchestration
Agent framework manages MCP.
┌──────────┐ ┌──────────────┐ ┌──────────────┐
│ Claude │─────→│ LangChain │─────→│ MCP Server │
│ │ │ (MCP Client)│ MCP │ │
└──────────┘ └──────────────┘ └──────────────┘
from langchain_mcp import MCPToolkit
toolkit = MCPToolkit("https://my-tools.gantz.run/sse")
agent = create_agent(llm=claude, tools=toolkit.get_tools())
Pattern 3: Multiple MCP servers
Different servers for different domains.
┌──────────────────┐
│ MCP Server 1 │
┌───→│ (Database) │
│ └──────────────────┘
┌──────────┐ │
│ AI │─┼───→┌──────────────────┐
│ Agent │ │ │ MCP Server 2 │
└──────────┘ │ │ (Email) │
│ └──────────────────┘
│
└───→┌──────────────────┐
│ MCP Server 3 │
│ (Calendar) │
└──────────────────┘
Pattern 4: MCP gateway
Single entry point to multiple backends.
┌──────────┐ ┌──────────────┐ ┌─────────────┐
│ AI │─────→│ MCP Gateway │─────→│ Service A │
│ Agent │ MCP │ │ ├─────────────┤
└──────────┘ │ │─────→│ Service B │
│ │ ├─────────────┤
│ │─────→│ Service C │
└──────────────┘ └─────────────┘
Real example
Let's trace a request through the stack:
User: "What's my top customer's email?"
1. User Interface
└─ User types question in chat
2. Application
└─ Request sent to backend
3. AI Orchestration
└─ Agent decides: "I need to query the database"
4. AI Model
└─ Claude generates tool call: query_customers
5. MCP Layer ← HERE
├─ MCP Client sends: tools/call "query_customers"
├─ MCP Server receives request
├─ Server executes: SELECT * FROM customers ORDER BY revenue DESC LIMIT 1
└─ Server returns result via MCP
6. External Systems
└─ PostgreSQL returns data
7. Back up the stack
└─ AI gets result → formulates answer → returns to user
MCP handled step 5 — the protocol layer between AI and database.
What MCP replaces
Before MCP, you'd write custom integration code:
# Old way: Custom integration per tool
def handle_tool_call(tool_name, params):
if tool_name == "query_db":
return custom_db_query(params)
elif tool_name == "send_email":
return custom_email_send(params)
elif tool_name == "search_files":
return custom_file_search(params)
# ... endless if/else
With MCP:
# New way: Standard protocol
mcp_client.call_tool(tool_name, params)
# MCP server handles the rest
Summary
MCP sits between AI and external systems.
Your AI app
↓
AI orchestration (decides what to do)
↓
MCP ← HERE (handles tool communication)
↓
Your tools and services
It's not the brain (AI model).
It's not the decision maker (orchestration).
It's not the data (external systems).
It's the nervous system — carrying signals between brain and body.
Where does MCP fit in your architecture? Running it locally or in the cloud?
Top comments (0)