lang: vi slug: mcp-deep-dive-definitive-2026-guide title: ‘Model Context Protocol (MCP) Deep Dive’ description: ‘Build your first MCP server from scratch. Learn Anthropic’’s Model Context Protocol with hands-on Python & TypeScript examples. Connect AI agents to real APIs, databases, and tools using the open standard adopted by OpenAI, Google, and Microsoft.’ tags: [“ai-tools”, “guide”, “mcp”, “model-context-protocol”, “open-source”, “reference”, “tutorial”] date: 2026-05-15 00:00:00+08:00 lastmod: 2026-05-15 00:00:00+08:00 tech_stack: [] application_domain: Llm Frameworks source_version: ’' licensing_model: Open Source license_type: MIT file_size: ’' file_md5: ’' download_url: ’' backup_url: ’' github_repo: ’' last_maintained: ‘2026-05-15’ draft: false aliases:
- /posts/mcp-deep-dive-definitive-2026-guide/
faqs:
- q: ‘What is the Model Context Protocol (MCP)?’ a: ‘MCP is an open standard, released by Anthropic in November 2024, that standardizes how AI models connect to external tools, APIs, and data sources. It runs on JSON-RPC 2.0 and acts like ‘‘USB-C for AI’’—a single port any model can use to plug into any tool. Since December 2025 it has been governed by the Linux Foundation’’s Agentic AI Foundation rather than Anthropic.’
- q: ‘What problem does MCP solve?’ a: ‘MCP solves the M×N integration problem, where connecting M LLM providers to N external tools previously required custom glue code for every pair. By having tool authors expose their tools once via an MCP server and LLM vendors implement one MCP client, the integration burden collapses from M×N to M+N.’
- q: ‘Which transport options does MCP support and when should I use each?’ a: ‘MCP supports stdio (fastest, zero network exposure, best for local development and desktop apps) and HTTP+SSE/Streamable HTTP (slightly higher latency but cross-machine and stream-capable, best for remote servers and production). The rule of thumb is to prototype with stdio and promote to HTTP/SSE for production.’
- q: ‘How many tools should a single MCP server expose?’ a: ‘Keep it under 10 tools per server. Too many tools degrade the LLM’’s selection accuracy and bloat the context window, since every tool definition is injected into the prompt. Split by functional domain—for example, one server for database operations and another for Slack operations.’
- q: ‘Is MCP a replacement for frameworks like LangChain, CrewAI, or the OpenAI Agents SDK?’ a: ‘No. MCP is a protocol—the plumbing for exposing tools—while LangChain chains calls, CrewAI orchestrates multi-agent workflows, and the OpenAI Agents SDK is a high-level agent builder. These frameworks increasingly consume MCP servers as their tool layer rather than competing with MCP.’
featureImage: /images/articles/mcpmodel-context-protocol-완벽-실전-가이드.png #
Headroom: Compress LLM Inputs by 60-95% • Persistent Memory for AI Coding Agents in 2026 {</* resource-info */>}
Introduction: Why MCP Is the Smartest Bet for Developers in 2026If you’re still writing custom integration code for every LLM and every tool, you’re doing 2025’s work in 2026.In November 2024, Anthropic quietly released the Model Context Protocol (MCP). Six months later, it had become the fastest-adopted open standard in AI infrastructure. OpenAI, Google DeepMind, and Microsoft all pledged native support. The community built 10,000+ MCP servers. Weekly downloads of the official Python and JavaScript SDKs crossed 20 million.Then in December 2025, the Linux Foundation spun up the Agentic AI Foundation to steward MCP independently. It is no longer Anthropic’s protocol. It is the industry’s protocol.This guide is not a high-level overview. You will write a real, production-grade MCP server that monitors website health and SSL certificates, then wire it into Claude Desktop, Cursor, and VS Code Copilot Agent Mode. By the end, you’ll have a working tool you can extend for your own APIs and deploy today.—## Table of Contents1. What MCP Actually Is (And What It Is Not) #
- Architecture: How Host, Client, and Server Talk
- Dev Environment in 5 Minutes
- Hands-On: Build a SiteMonitor MCP Server
- Connect to Claude Desktop, Cursor, and VS Code
- Level Up: Resources, Prompts, and HTTP/SSE Transport
- Security & Production Hardening
- MCP Ecosystem Cheat Sheet: 15 Servers to Try Now
- FAQ—## 1. What MCP Actually Is (And What It Is Not)### The M×N ProblemBefore MCP, integrating LLMs with external tools was a combinatorial nightmare:- M LLM providers (OpenAI, Anthropic, Google, Meta, Mistral…)
- N external tools (GitHub, Postgres, Slack, Stripe, Salesforce…)
- Custom glue code for every pairMCP collapses this to M + N:- Tool authors expose once via MCP (Server)
- LLM vendors implement one MCP client
- Everything just works togetherThink of it as USB-C for AI: a single, standardized port that any model can use to plug into any data source or tool.### What MCP Is Not| Misconception | Reality | |—————|———| | A new AI model | No—it’s a protocol, not a model | | A replacement for Function Calling | No—MCP standardizes how tools are exposed; Function Calling is how models invoke them. They stack together. | | Only for Claude | No—OpenAI, Google, Microsoft, Cursor, Zed, Sourcegraph all support it | | Anthropic-proprietary | No—governed by the Linux Foundation since Dec 2025 |### Who Supports MCP (May 2026)| Platform | Support Level | Notes | |———-|—————|——-| | Claude Desktop / Claude Code | Native | Reference implementation | | ChatGPT | Full (Dev Mode) | Read/write, Plus/Pro tiers since Sept 2025 | | Google Gemini | Confirmed | DeepMind CEO announced roadmap | | Cursor / Windsurf / Zed | Supported | AI-native IDEs | | VS Code Copilot Agent Mode | Native | v1.99+ | | Sourcegraph Cody | Enterprise | Enterprise MCP adoption |—## 2. Architecture: How Host, Client, and Server TalkMCP runs on JSON-RPC 2.0 over two transport options. Four concepts cover 90% of real-world usage.### The Four Concepts``` ┌─────────────────────────────────────────────────────┐ │ MCP Host │ │ ┌─────────────┐ ┌──────────────────────┐ │ │ │ LLM │◄────────►│ MCP Client(s) │ │ │ │ (Claude) │ │ (stdio / HTTP+SSE) │ │ │ └─────────────┘ └──────────┬─────────────┘ │ └───────────────────────────────────────┼──────────────┘ │ JSON-RPC 2.0 ┌───────────────────────────────────────┼──────────────┐ │ MCP Server │ │ │ • Tools (callable functions) │◄─────────────┘ │ • Resources (readable data) │ │ • Prompts (reusable templates) │ └─────────────────────────────────────────────────────┘
**Client**: The module inside the Host that speaks MCP.
**Server**: A standalone process exposing tools/resources/prompts.### Three Interaction Primitives1. **Tools**: Functions the AI can call with arguments, receiving structured results.
2. **Resources**: Read-only data the AI can fetch (files, DB rows, configs).
3. **Prompts**: Named, parameterized prompt templates the AI can invoke.### Transport Options| Transport | Best For | Trade-off |
|-----------|----------|-----------|
| **stdio** | Local dev, desktop apps | Fastest, zero network exposure, limited to single machine |
| **HTTP + SSE** | Remote servers, microservices | Slightly higher latency, cross-machine, supports streaming |
| **Streamable HTTP** | Production, serverless | Stateful fallback, long-running ops |**Rule of thumb**: Prototype with stdio. Promote to HTTP/SSE for production.---## 3. Dev Environment in 5 MinutesOfficial SDKs exist for Python, TypeScript, C#/.NET, Java/Kotlin, and Go (community). We'll use **Python** for speed and **TypeScript** as a parallel reference.### Install uv (Fast Python Package Manager)```
bas
h
curl -LsSf https://astral.sh/uv/install.sh | sh
```### Scaffold the Project```
bas
h
mkdir mcp-site-monitor && cd mcp-site-monitor
uv init
uv add "mcp[cli]" httpx
```Direct
o
r
y
layout:```
mcp-site-monitor/
├── .env # Secrets (gitignored)
├── .gitignore
├── pyproject.toml
└── server.py # Main MCP server
```---## 4. Hands-On: Build a SiteMonitor MCP ServerWe'll expose two tools:- `check_site_status` — HTTP health check with timing
- `check_ssl_expiry` — Days remaining on an SSL certificate### Complete Python Server (`server.py`)```
pytho
n
import asyncio
import ssl
import socket
from datetime import datetimeimport httpx
from mcp.server.fastmcp import FastMCPmcp = FastMCP("SiteMonitor")@mcp.tool()
asyn```
bas
h
curl -LsSf https://astral.sh/uv/install.sh | sh
```:
"""Check whether a website is online and measure response time. Args:```
bas
h
mkdir mcp-site-monitor && cd mcp-site-monitor
uv init
uv add "mcp[cli]" httpx
```t
before failing, default 10.
"""
try:
async with httpx.AsyncClient(follow_redirects=Tr```
mcp-site-monitor/
├── .env # Secrets (gitignored)
├── .gitignore
├── pyproject.toml
└── server.py # Main MCP server
```nc
i
o
.get_event_loop().time() - t0 status = "✅ Online" if r.status_code < 400 else "⚠️ Degraded"
return (
f"{status}\n"
f"• URL: {url}\n"
f"• Status: {r.status_code}\n"
f"• Response time: {elapsed:.2f}s\n"
f"• Server: {r.headers.get('server', 'unknown')}\n"
```
pytho
n
import asyncio
import ssl
import socket
from datetime import datetime
import httpx
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("SiteMonitor")
@mcp.tool()
async def check_site_status(url: str, timeout: int = 10) -> str:
"""Check whether a website is online and measure response time.
Args:
url: Full URL to check, e.g. https://example.com
timeout: Seconds to wait before failing, default 10.
"""
try:
async with httpx.AsyncClient(follow_redirects=True, timeout=timeout) as client:
t0 = asyncio.get_event_loop().time()
r = await client.get(url)
elapsed = asyncio.get_event_loop().time() - t0
status = "✅ Online" if r.status_code < 400 else "⚠️ Degraded"
return (
f"{status}\n"
f"• URL: {url}\n"
f"• Status: {r.status_code}\n"
f"• Response time: {elapsed:.2f}s\n"
f"• Server: {r.headers.get('server', 'unknown')}\n"
)
except httpx.TimeoutException:
return f"❌ Timeout: {url} did not respond within {timeout}s"
except Exception as e:
return f"❌ Error: {type(e).__name__}: {e}"
@mcp.tool()
async def check_ssl_expiry(hostname: str, port: int = 443) -> str:
"""Check how many days remain on a domain's SSL certificate.
Args:
hostname: Domain name, e.g. example.com
port: HTTPS port, default 443.
"""
try:
ctx = ssl.create_default_context()
with socket.create_connection((hostname, port), timeout=10) as sock:
with ctx.wrap_socket(sock, server_hostname=hostname) as ssock:
cert = ssock.getpeercert()
expiry = datetime.strptime(cert["notAfter"], "%b %d %H:%M:%S %Y %Z")
days = (expiry - datetime.utcnow()).days
flag = "🟢 Healthy" if days > 30 else "🟡 Expiring soon" if days > 7 else "🔴 Critical"
return (
f"{flag}\n"
f"• Host: {hostname}\n"
f"• Issuer: {cert.get('issuer', 'unknown')}\n"
f"• Expires: {expiry.strftime('%Y-%m-%d %H:%M UTC')}\n"
f"• Days left: {days}\n"
)
except Exception as e:
return f"❌ SSL check failed: {type(e).__name__}: {e}"
if __name__ == "__main__":
mcp.run(transport="stdio")
``` async ({ url, timeout = 10 }) => {
// ... httpx equivalent with fetch/axios
return { content: [{ type: "text", text: result }] };
}
);const transport = new StdioServerTransport();
await server.connect(transport);
```---## 5. Connect to Claude Desktop, Cursor, and VS Code### Claude Desktop (macOS)Edit:```
bas
h
~/Library/Application\ Support/Claude/claude_desktop_config.json
```A
d
d
:```
jso
n
{
"mcpServers": {
"site-monitor": {
"command": "uv",
"args": [
"run",
"--directory",
"/absolute/path/to/mcp-site-monitor",
"server.py"
]
}
}
}
```Rest
a
r
t
Claude Desktop. Ask:> "Check if https://github.com is up and tell me how many days are left on its SSL cert."Claude invokes both tools automatically and formats the results.### CursorCreate `.cursor/mcp.json` in your project root:```
jso
n
{
"mcpServers": {
"site-monitor": {
"command": "uv",
"args": [
"run",
"--directory",
"/absolute/path/to/mcp-site-monitor",
"server.py"
]
}
}
}
```Curs
o
r
's AI Chat discovers and uses the tools inline.### VS Code Copilot Agent ModeIn `settings.json`:```
jso
n
{
"github.copilot.chat.mcpServers": {
"site-monitor": {
"command": "uv",
"args": ["run", "server.py"],
"cwd": "/absolute/path/to/mcp-site-monitor"
}
}
}
```---## 6. Level Up: Resources, Prompts, and HTTP/SSE Transport### Exposing Resources (Read-Only Data)```
pytho
n
@mcp.resource("config://app")
def get_app_config() -> str:
"""Return current application configuration."""
import json
return json.dumps({"check_interval_sec": 300, "alert_threshold_ms": 2000})@mcp.resource("log://latest")
def get_latest_log() -> str:
"""Return the most recent monitoring log entry."""
return "[2026-05-15T08:00:00Z] github.com: 200 OK in 23ms"
```### Exposing Prompts (Reusable Templates)```
pytho
n
@mcp.prompt()
def debug_incident(url: str, status_code: int) -> str:
"""Generate a structured incident-debugging prompt."""
return f"""Website {url} is returning HTTP {status_code}. Investigate:
1. DNS resolution health
2. Server process status
3. Recent application logs (last 10 min)
4. Traffic spike patterns from the CDN dashboard
"""
```### Switching to HTTP + SSE for Production```
pytho
n
from mcp.server.sse import SseServerTransport
from starlette.applications import Starlette
from starlette.routing import Routesse = SseServerTransport("/messages/")async def handle_sse(request):
async with sse.connect_sse(request.scope, request.receive, request._send) as streams:
await mcp.run(streams[0], streams[1], mcp.create_initialization_options())app = Starlette(routes=[Route("/sse", endpoint=handle_sse)])
```Dep
l
o
y
to any ASGI host (Railway, Fly.io, your own VPS) and point remote clients to the SSE endpoint.---## 7. Security & Production HardeningConnecting AI to external systems is powerful and dangerous. Fo```
typescrip
t
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
const server = new McpServer({ name: "SiteMonitor", version: "1.0.0" });
server.tool(
"check_site_status",
{
url: z.string().describe("Full URL to check"),
timeout: z.number().optional().describe("Timeout in seconds"),
},
async ({ url, timeout = 10 }) => {
// ... httpx equivalent with fetch/axios
return { content: [{ type: "text", text: result }] };
}
);
const transport = new StdioServerTransport();
await server.connect(transport);
``` Prevent MITM tampering with tool calls.
7. **Audit & monitor** — Log every tool invocation. Alert on anomalies.**Real-world warning**: In July 2025, a critical RCE vulnerability (CVE-2025-49596, CVSS 9.4) was found in Anthropic's MCP Inspector. Browser-based attacks against AI dev tools are now a known threat class. Treat MCP servers as security-critical infrastructure.---## 8. MCP Ecosystem Cheat Sheet: 15 Servers to Try Now| Server | What It Does | Best Use Case |
|--------|--------------|---------------|
| **filesystem** | Read/write local files | Codebase analysis, doc processing |
| **github** | PRs, issues, code search | Automated code review |
| **postgres** / **sqlite** | SQL queries | Data analysis, internal BI |
| **sl```
bas
h
~/Library/Application\ Support/Claude/claude_desktop_config.json
``` **brave-search** | Web search | Real-time fact checking |
| **puppeteer** | ```
jso
n
{
"mcpServers": {
"site-monitor": {
"command": "uv",
"args": [
"run",
"--directory",
"/absolute/path/to/mcp-site-monitor",
"server.py"
]
}
}
}
```managem
e
n
t
|
| **fetch** | Arbitrary URL fetching | Content summarization |
| **sequential-thinking** | Chain-of-thought helper | Complex reasoning tasks |
| **playwright** | E2E test automation | Test generation |
| **redis** | Key-value operations | Cache inspection |
| **docker** | Container management | DevOps automation |
| **kubernetes** | K8s resource ops | Cluster management |Full directories: [Smithery.ai](https://smithery.ai) · [MCP.so](https:```
jso
n
{
"mcpServers": {
"site-monitor": {
"command": "uv",
"args": [
"run",
"--directory",
"/absolute/path/to/mcp-site-monitor",
"server.py"
]
}
}
}
```ag
e
n
t
workflows. OpenAI Agents SDK is a high-level agent builder. These frameworks increasingly **consume** MCP servers as their tool layer.**Q: Can I run MCP servers in the cloud / on Kubernetes?**Yes. stdio is for local. HTTP/SSE scales to containers, VPS, and serverless (with caveats around MCP's stateful desig```
jso
n
{
"github.copilot.chat.mcpServers": {
"site-monitor": {
"command": "uv",
"args": ["run", "server.py"],
"cwd": "/absolute/path/to/mcp-site-monitor"
}
}
}
```i
o
n
accuracy and bloat the context window (every tool definition is injected into the prompt). Split by functional domain: one server for DB ops, another for Slack ops.**Q: What's the relationship between MCP and Google's A2A protocol?**MCP connects **AI → Tools** (agent to external system)```
pytho
n
@mcp.resource("config://app")
def get_app_config() -> str:
"""Return current application configuration."""
import json
return json.dumps({"check_interval_sec": 300, "alert_threshold_ms": 2000})
@mcp.resource("log://latest")
def get_latest_log() -> str:
"""Return the most recent monitoring log entry."""
return "[2026-05-15T08:00:00Z] github.com: 200 OK in 23ms"
```e
technology. It is the **live standard** for AI tool integration in 2026. If you don't know how to build an MCP server today, you're missing the foundational skill that every AI-native dev team will expect tomorrow.Your next steps:1. Copy the SiteMonitor code above and run it with `uv`
2. Wire it into Claude Desktop and ask a natural-language monitoring question
3. Wrap your team's most-used internal API as an MCP server
4. P```
pytho
n
@mcp.prompt()
def debug_incident(url: str, status_code: int) -> str:
"""Generate a structured incident-debugging prompt."""
return f"""Website {url} is returning HTTP {status_code}. Investigate:
1. DNS resolution health
2. Server process status
3. Recent application logs (last 10 min)
4. Traffic spike patterns from the CDN dashboard
"""
```y
Marketplace](https://mcp.so)---## 🔌 Skip the Schema BoilerplateWriting JSON Schema by hand for every tool is the most tedious part of MCP development. Use dibi8's free **[MCP Tool Builder](/tools/mcp-tool-builder/)** — paste a Python or TypeScript function signature and get a spec-compliant tool definition + full server boilerplate (FastMCP / TypeScript SDK) + a cURL test command. Saves ```
pytho
n
from mcp.server.sse import SseServerTransport
from starlette.applications import Starlette
from starlette.routing import Route
sse = SseServerTransport("/messages/")
async def handle_sse(request):
async with sse.connect_sse(request.scope, request.receive, request._send) as streams:
await mcp.run(streams[0], streams[1], mcp.create_initialization_options())
app = Starlette(routes=[Route("/sse", endpoint=handle_sse)])
```r
o
m
mainland China. This is the same IDC that hosts dibi8.com — battle-tested in production.*Affiliate links — they don't cost you extra and they help keep dibi8.com running.**Published May 15, 2026. Based on MCP Protocol Specification 2025-11-25 (One-Year Anniversary Release).*<!--auto-references-->
## References & Sources- [MCP Specification](https://modelcontextprotocol.io)
- [MCP Python SDK (FastMCP)](https://github.com/modelcontextprotocol/python-sdk)
- [MCP TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk)
- [MCP Reference Servers (filesystem, github, postgres, slack, etc.)](https://github.com/modelcontextprotocol/servers)
- [Smithery.ai (MCP Server Registry)](https://smithery.ai)
- [MCP.so (Community Marketplace)](https://mcp.so)
- [uv (Python package manager)](https://github.com/astral-sh/uv)
💬 Bình luận & Thảo luận