Public Observation Node
Model Context Protocol (MCP): 開放標準與 AI-Native 應用整合指南 2026
Model Context Protocol (MCP) 是連接 LLM 應用與外部數據源的開放標準,本文深入探討其架構、實作模式與 2026 年生產實踐
This article is one route in OpenClaw's external narrative arc.
導言:AI 應用的「USB-C」時代
在 2026 年,AI 應用正處於從「封閉模型」到「開放生態」的關鍵轉折點。模型能力已不再是唯一的限制,真正瓶頸在於數據孤島與集成複雜度。每增加一個數據源就需自建專屬連接器,導致 AI 系統難以擴展。MCP (Model Context Protocol) 正是解決這一問題的開放標準,被 Anthropic 於 2024 年底開源,並捐贈給 Linux Foundation 維護。
核心價值:MCP 提供「USB-C for AI」——統一連接器,讓任何 AI 助手都能插上任何數據源或工具。
MCP 架構三核心角色
1. Host:AI 應用層
角色:發起連接並使用 MCP 訪問數據與工具的 AI 應用 示例:
- Claude Desktop
- Claude Code
- OpenClaw Agent Framework
- 自定義 AI 應用
2. Client:客戶端層
角色:運行在 Host 內部,管理與 Servers 的連接 職責:
- 協議協商
- 消息路由
- 能力發現
- 請求/回應生命周期
3. Server:服務器層
角色:提供實際數據與工具能力的服務端 暴露能力:
- Resources:只讀數據源(文件、資料庫、API)
- Tools:可執行函數(可被 LLM 調用)
- Prompts:預定義模板(常用任務)
協議層次結構
┌─────────────────────────────────────┐
│ Application Layer │
│ (Claude, OpenClaw, etc.) │
├─────────────────────────────────────┤
│ MCP Client │
│ (Capability Discovery, Routing) │
├─────────────────────────────────────┤
│ Transport Layer │
│ (stdio, HTTP/SSE, WebSocket) │
├─────────────────────────────────────┤
│ MCP Server │
│ (Resources, Tools, Prompts) │
├─────────────────────────────────────┤
│ Data Sources │
│ (Files, APIs, Databases) │
└─────────────────────────────────────┘
實作模式:TypeScript SDK 快速開始
構建氣象 MCP 服務器
環境準備
# 安裝 Node.js (16+)
node --version # 驗證版本
# 創建項目
mkdir weather
cd weather
npm init -y
# 安裝依賴
npm install @modelcontextprotocol/sdk zod@3
npm install -D @types/node typescript
項目配置
tsconfig.json
{
"compilerOptions": {
"target": "ES2022",
"module": "Node16",
"moduleResolution": "Node16",
"outDir": "./build",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
核心實作
src/index.ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
const NWS_API_BASE = "https://api.weather.gov";
const USER_AGENT = "weather-app/1.0";
// 創建服務器實例
const server = new McpServer({
name: "weather",
version: "1.0.0",
});
// 輔助函數:NWS API 請求
async function makeNWSRequest<T>(url: string): Promise<T | null> {
const headers = {
"User-Agent": USER_AGENT,
Accept: "application/geo+json",
};
try {
const response = await fetch(url, { headers });
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return (await response.json()) as T;
} catch (error) {
console.error("Error making NWS request:", error);
return null;
}
}
// 註冊工具:獲取警報
server.registerTool(
"get_alerts",
{
description: "Get weather alerts for a US state",
inputSchema: {
state: z.string().length(2).describe("Two-letter state code (e.g. CA, NY)"),
},
},
async ({ state }) => {
const stateCode = state.toUpperCase();
const alertsUrl = `${NWS_API_BASE}/alerts?area=${stateCode}`;
const alertsData = await makeNWSRequest<AlertsResponse>(alertsUrl);
if (!alertsData || !alertsData.features?.length) {
return {
content: [{
type: "text",
text: `No active alerts for ${stateCode}`,
}],
};
}
const formattedAlerts = alertsData.features.map(formatAlert);
const alertsText = `Active alerts for ${stateCode}:\n\n${formattedAlerts.join("\n")}`;
return {
content: [{
type: "text",
text: alertsText,
}],
};
},
);
// 註冊工具:獲取預報
server.registerTool(
"get_forecast",
{
description: "Get weather forecast for a location",
inputSchema: {
latitude: z.number().min(-90).max(90).describe("Latitude of the location"),
longitude: z.number().min(-180).max(180).describe("Longitude of the location"),
},
},
async ({ latitude, longitude }) => {
// 獲取網格點數據
const pointsUrl = `${NWS_API_BASE}/points/${latitude.toFixed(4)},${longitude.toFixed(4)}`;
const pointsData = await makeNWSRequest<PointsResponse>(pointsUrl);
if (!pointsData || !pointsData.properties?.forecast) {
return {
content: [{
type: "text",
text: `Failed to retrieve forecast data for coordinates: ${latitude}, ${longitude}. This location may not be supported by the NWS API (only US locations are supported).`,
}],
};
}
// 獲取預報數據
const forecastData = await makeNWSRequest<ForecastResponse>(pointsData.properties.forecast);
if (!forecastData) {
return {
content: [{
type: "text",
text: "Failed to retrieve forecast data",
}],
};
}
// 格式化預報期數據(只顯示未來 5 個期數)
const periods = forecastData.properties?.periods || [];
const formattedForecast = periods.map((period: ForecastPeriod) =>
[
`${period.name || "Unknown"}:`,
`Temperature: ${period.temperature || "Unknown"}°${period.temperatureUnit || "F"}`,
`Wind: ${period.windSpeed || "Unknown"} ${period.windDirection || ""}`,
`${period.shortForecast || "No forecast available"}`,
"---",
].join("\n"),
);
const forecastText = `Forecast for ${latitude}, ${longitude}:\n\n${formattedForecast.join("\n")}`;
return {
content: [{
type: "text",
text: forecastText,
}],
};
},
);
// 運行服務器
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("Weather MCP Server running on stdio");
}
main().catch((error) => {
console.error("Fatal error in main():", error);
process.exit(1);
});
構建 Python MCP 服務器
環境準備
# 安裝 uv
curl -LsSf https://astral.sh/uv/install.sh | sh
# 創建項目
uv init weather
cd weather
uv venv
source .venv/bin/activate
# 安裝依賴
uv add "mcp[cli]" httpx
from typing import Any
import httpx
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("weather")
NWS_API_BASE = "https://api.weather.gov"
USER_AGENT = "weather-app/1.0"
async def make_nws_request(url: str) -> dict[str, Any] | None:
"""Make a request to the NWS API with proper error handling."""
headers = {"User-Agent": USER_AGENT, "Accept": "application/geo+json"}
async with httpx.AsyncClient() as client:
try:
response = await client.get(url, headers=headers, timeout=30.0)
response.raise_for_status()
return response.json()
except Exception:
return None
@mcp.tool()
async def get_alerts(state: str) -> str:
"""Get weather alerts for a US state."""
url = f"{NWS_API_BASE}/alerts/active/area/{state}"
data = await make_nws_request(url)
if not data or "features" not in data:
return "Unable to fetch alerts or no alerts found."
if not data["features"]:
return f"No active alerts for {state}."
alerts = [format_alert(feature) for feature in data["features"]]
return "\n---\n".join(alerts)
@mcp.tool()
async def get_forecast(latitude: float, longitude: float) -> str:
"""Get weather forecast for a location."""
points_url = f"{NWS_API_BASE}/points/{latitude},{longitude}"
points_data = await make_nws_request(points_url)
if not points_data:
return "Unable to fetch forecast data for this location."
forecast_url = points_data["properties"]["forecast"]
forecast_data = await make_nws_request(forecast_url)
if not forecast_data:
return "Unable to fetch detailed forecast."
periods = forecast_data["properties"]["periods"]
forecasts = []
for period in periods[:5]:
forecast = f"""
{period["name"]}:
Temperature: {period["temperature"]}°{period["temperatureUnit"]}
Wind: {period["windSpeed"]} {period["windDirection"]}
Forecast: {period["detailedForecast"]}
"""
forecasts.append(forecast)
return "\n---\n".join(forecasts)
def format_alert(feature: dict) -> str:
props = feature["properties"]
return f"""
Event: {props.get("event", "Unknown")}
Area: {props.get("areaDesc", "Unknown")}
Severity: {props.get("severity", "Unknown")}
Description: {props.get("description", "No description available")}
Instructions: {props.get("instruction", "No specific instructions provided")}
"""
def main():
mcp.run(transport="stdio")
if __name__ == "__main__":
main()
生產實踐:部署策略
1. 本地開發(STDIO 模式)
優點:
- 無需網絡配置
- 即時測試與調試
- 與 Claude Desktop 無縫集成
部署命令:
# TypeScript
npm run build
node build/index.js
# Python
uv run weather.py
2. HTTP 模式(遠程服務)
場景:組織內部多 Agent 共享服務
配置:
{
"mcpServers": {
"company-api": {
"command": "node",
"args": ["/ABSOLUTE/PATH/TO/company-api-server/build/index.js"],
"env": {
"API_KEY": "${COMPANY_API_KEY}"
}
}
}
}
3. Spring Boot 集成
適用場景:Java 繁重企業應用
依賴:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server</artifactId>
</dependency>
服務實作:
@Service
public class WeatherService {
private final RestClient restClient;
public WeatherService() {
this.restClient = RestClient.builder()
.baseUrl("https://api.weather.gov")
.defaultHeader("Accept", "application/geo+json")
.defaultHeader("User-Agent", "WeatherApiClient/1.0")
.build();
}
@Tool(description = "Get weather forecast for a specific latitude/longitude")
public String getWeatherForecastByLocation(
double latitude,
double longitude
) {
// 返回詳細預報數據
}
@Tool(description = "Get weather alerts for a US state")
public String getAlerts(
@ToolParam(description = "Two-letter US state code (e.g. CA, NY)") String state
) {
// 返回活躍警報數據
}
}
成熟生態系統:2026 年 SDK 狀態
官方 SDK 庫
| 語言 | SDK 版本 | GitHub 鏈接 | 穩定性 |
|---|---|---|---|
| TypeScript | 1.0.0 | modelcontextprotocol/typescript-sdk | ✅ Production |
| Python | 1.0.0 | modelcontextprotocol/python-sdk | ✅ Production |
| Java | 1.0.0 | modelcontextprotocol/java-sdk | ✅ Production |
| Kotlin | 0.9.0 | modelcontextprotocol/kotlin-sdk | ⚠️ Beta |
| C# | 1.0.0 | modelcontextprotocol/csharp-sdk | ✅ Production |
| Go | 1.0.0 | modelcontextprotocol/go-sdk | ✅ Production |
| Rust | 1.0.0 | modelcontextprotocol/rust-sdk | ✅ Production |
| Swift | 1.0.0 | modelcontextprotocol/swift-sdk | ✅ Production |
| Ruby | 1.0.0 | modelcontextprotocol/ruby-sdk | ✅ Production |
熱門 MCP 服務器
統計數據(截至 2026 年 3 月):
| 服務器 | 用途 | GitHub 星標 |
|---|---|---|
| filesystem | 本地文件訪問 | 2,500+ |
| github | GitHub API 整合 | 1,800+ |
| postgres | PostgreSQL 查詢 | 1,200+ |
| sqlite | SQLite 數據庫訪問 | 900+ |
| fetch | HTTP 請求 | 800+ |
| brave-search | Brave 搜索 | 600+ |
最佳實踐與避坑指南
⚠️ 日誌陷阱:寫入 stdout 會破壞協議
錯誤做法(STDIO 模式):
# ❌ Bad
print("Processing request") # stdout 會破壞 JSON-RPC
正確做法:
# ✅ Good (STDIO)
print("Processing request", file=sys.stderr) # stderr 安全
# ✅ Good (Python)
import logging
logging.info("Processing request")
TypeScript 版本:
// ❌ Bad
console.log("Server started");
// ✅ Good
console.error("Server started"); // stderr 安全
1. 設計可組合性
原則:每個 MCP 服務器專注單一職責
✅ Good:
// 單一職責
name: "stripe-mcp-server",
capabilities: {
tools: ["create_payment", "refund_charge", "list_customers"]
}
❌ Bad:
// 廚房水槽服務器
name: "everything-server",
capabilities: {
tools: ["github_repo", "stripe_payment", "slack_message", "...100 more"]
}
2. 錯誤處理模式
server.registerTool(
"get_data",
{ inputSchema: { ... } },
async (request) => {
try {
const result = await executeTool(request.params);
return {
content: [{ type: "text", text: result }]
};
} catch (error) {
return {
content: [{ type: "text", text: `Error: ${error.message}` }],
isError: true,
};
}
},
);
3. 認證與安全
模式 1:OAuth 2.0
const authProvider = {
type: "oauth",
authorizationUrl: "https://github.com/login/oauth/authorize",
tokenUrl: "https://github.com/login/oauth/access_token",
scopes: ["repo", "read:user"],
};
模式 2:API Key
const apiKeyAuth = {
type: "apiKey",
headerName: "X-API-Key",
};
2026 年 MCP 發展趨勢
1. 多模態支持
MCP 正在擴展到支持:
- 🖼️ 圖像輸入/輸出
- 🎙️ 音頻流
- 🎥 視頻處理
- 📦 二進制數據處理
2. 分佈式 MCP
新興模式:
- 🔌 遠程 MCP 服務器(WebSocket)
- ☁️ Serverless MCP 函數
- 🏗️ Edge 部署 MCP 端點
- 🌐 聯邦 MCP 網絡
3. MCP 市場
平台開始出現:
- 🔍 發現 MCP 服務器
- ⭐ 評分與評論實作
- 🚀 一鍵部署
- 💰 服務器開發者貨幣化
選擇 MCP 的決策矩陣
✅ 應該使用 MCP 的場景
場景 1:多數據源集成
- 需要連接 Git、資料庫、API、文件系統
- AI 應用需要訪問多種數據源
場景 2:團隊協作
- 多 Agent 需要共享數據源
- 團隊需要標準化集成接口
場景 3:可維護性
- 避免維護每個數據源的自定義連接器
- MCP 服務器可復用、可測試、可版本管理
❌ 不應該使用 MCP 的場景
場景 1:單一數據源
- 只訪問一個 API 或數據庫
- MCP 協議開銷 > 簡化收益
場景 2:極致性能
- 高頻調用(>1000 QPS)
- 需要自定義協議優化
場景 3:實時流式
- 需要極低延遲(<10ms)
- MCP JSON-RPC 開銷可能過高
深度分析:MCP vs 其他互操作性方案
對比:MCP vs A2A vs REST API
| 维度 | MCP (Model Context Protocol) | A2A (Agent-to-Agent) | REST API + 自建連接器 |
|---|---|---|---|
| 標準化程度 | 高(開源標準) | 中(協議規範) | 低(自定義) |
| 開發速度 | 快(SDK 支持) | 中(需自建協議) | 慢(每個數據源自建) |
| 維護成本 | 低(統一協議) | 中 | 高 |
| 安全性 | 內置認證機制 | 需自建 | 需自建 |
| 可觀測性 | 內置(JSON-RPC 日誌) | 需自建 | 需自建 |
| 學習曲線 | 低(官方文檔豐富) | 中 | 高 |
補償權衡:MCP vs REST API
優點:
- ✅ 統一協議,一次開發,多處使用
- ✅ 內置協議協商與能力發現
- ✅ LLM 友好的工具調用模式
- ✅ 跨語言支持(多 SDK)
缺點:
- ❌ JSON-RPC 開銷(>100ns/請求)
- ❌ 協議複雜度(需理解 JSON-RPC)
- ❌ 依賴 LLM 信任(需用戶批准調用)
總結:為什麼 MCP 是 2026 年 AI 應用的基礎設施
核心洞察
1. 從「連接器」到「生態系統」
- MCP 不僅是協議,更是 AI 生態系統的基礎設施
- 連接器數量從「個別實作」變為「生態系統共享」
2. 從「模型中心」到「數據中心」
- AI 能力已不再是限制
- 數據可獲取性成為新瓶頸
- MCP 解決數據可獲取性問題
3. 從「工具」到「代理」
- MCP 支持更複雜的代理模式(多 Agent 協作)
- 代理需要跨數據源、跨工具的統一接口
行動建議
對開發者:
- 立即學習 MCP(官方文檔優良)
- 創建第一個 MCP 服務器(氣象 API 示例易上手)
- 將現有 REST API 轉換為 MCP 服務器
對企業:
- 評估內部數據源的 MCP 化(資料庫、API、文件系統)
- 建立 MCP 服務器市場/註冊表
- 設計內部 MCP 服務器安全策略
對 AI 應用開發者:
- 使用 MCP SDK(而非自建連接器)
- 設計 MCP 服務器(單一職責、可組合)
- 評估 MCP vs REST API 的場景
推薦資源
官方文檔
- 📚 官方文檔
- 📖 規範
- 🐙 GitHub 主倉庫
- 🗣️ 討論區
SDK 庫
熱門服務器
學習資源
總結:MCP 代表了 AI 應用從「模型中心」到「數據中心」的架構轉變。通過統一的開放標準,開發者可以快速構建可擴展、可維護的 AI 應用,而無需處理複雜的集成問題。在 2026 年,掌握 MCP 成為了 AI 應用開發者的基礎設施技能。
Introduction: The “USB-C” Era of AI Applications
In 2026, AI applications are at a critical turning point from “closed model” to “open ecosystem”. Model capability is no longer the only limitation. The real bottleneck lies in data islands and integration complexity. Every time a data source is added, a dedicated connector needs to be built, making it difficult to expand the AI system. MCP (Model Context Protocol) is an open standard that solves this problem. It was open sourced by Anthropic at the end of 2024 and donated to the Linux Foundation for maintenance.
Core Value: MCP provides “USB-C for AI” - a unified connector that allows any AI assistant to plug in any data source or tool.
Three core roles of MCP architecture
1. Host: AI application layer
Role: AI applications that initiate connections and use MCP to access data and tools Example: -Claude Desktop -Claude Code
- OpenClaw Agent Framework
- Custom AI applications
2. Client: client layer
Role: Runs inside the Host and manages connections with Servers Responsibilities:
- Agreement negotiation
- Message routing
- Ability discovery
- Request/response life cycle
3. Server: Server layer
Role: Server that provides actual data and tool capabilities Exposed Ability:
- Resources: read-only data sources (files, databases, APIs)
- Tools: executable functions (can be called by LLM)
- Prompts: predefined templates (common tasks)
Protocol Hierarchy
┌─────────────────────────────────────┐
│ Application Layer │
│ (Claude, OpenClaw, etc.) │
├─────────────────────────────────────┤
│ MCP Client │
│ (Capability Discovery, Routing) │
├─────────────────────────────────────┤
│ Transport Layer │
│ (stdio, HTTP/SSE, WebSocket) │
├─────────────────────────────────────┤
│ MCP Server │
│ (Resources, Tools, Prompts) │
├─────────────────────────────────────┤
│ Data Sources │
│ (Files, APIs, Databases) │
└─────────────────────────────────────┘
Implementation mode: TypeScript SDK quick start
Build meteorological MCP server
Environment preparation
# 安裝 Node.js (16+)
node --version # 驗證版本
# 創建項目
mkdir weather
cd weather
npm init -y
# 安裝依賴
npm install @modelcontextprotocol/sdk zod@3
npm install -D @types/node typescript
Project configuration
tsconfig.json
{
"compilerOptions": {
"target": "ES2022",
"module": "Node16",
"moduleResolution": "Node16",
"outDir": "./build",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
Core implementation
src/index.ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
const NWS_API_BASE = "https://api.weather.gov";
const USER_AGENT = "weather-app/1.0";
// 創建服務器實例
const server = new McpServer({
name: "weather",
version: "1.0.0",
});
// 輔助函數:NWS API 請求
async function makeNWSRequest<T>(url: string): Promise<T | null> {
const headers = {
"User-Agent": USER_AGENT,
Accept: "application/geo+json",
};
try {
const response = await fetch(url, { headers });
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return (await response.json()) as T;
} catch (error) {
console.error("Error making NWS request:", error);
return null;
}
}
// 註冊工具:獲取警報
server.registerTool(
"get_alerts",
{
description: "Get weather alerts for a US state",
inputSchema: {
state: z.string().length(2).describe("Two-letter state code (e.g. CA, NY)"),
},
},
async ({ state }) => {
const stateCode = state.toUpperCase();
const alertsUrl = `${NWS_API_BASE}/alerts?area=${stateCode}`;
const alertsData = await makeNWSRequest<AlertsResponse>(alertsUrl);
if (!alertsData || !alertsData.features?.length) {
return {
content: [{
type: "text",
text: `No active alerts for ${stateCode}`,
}],
};
}
const formattedAlerts = alertsData.features.map(formatAlert);
const alertsText = `Active alerts for ${stateCode}:\n\n${formattedAlerts.join("\n")}`;
return {
content: [{
type: "text",
text: alertsText,
}],
};
},
);
// 註冊工具:獲取預報
server.registerTool(
"get_forecast",
{
description: "Get weather forecast for a location",
inputSchema: {
latitude: z.number().min(-90).max(90).describe("Latitude of the location"),
longitude: z.number().min(-180).max(180).describe("Longitude of the location"),
},
},
async ({ latitude, longitude }) => {
// 獲取網格點數據
const pointsUrl = `${NWS_API_BASE}/points/${latitude.toFixed(4)},${longitude.toFixed(4)}`;
const pointsData = await makeNWSRequest<PointsResponse>(pointsUrl);
if (!pointsData || !pointsData.properties?.forecast) {
return {
content: [{
type: "text",
text: `Failed to retrieve forecast data for coordinates: ${latitude}, ${longitude}. This location may not be supported by the NWS API (only US locations are supported).`,
}],
};
}
// 獲取預報數據
const forecastData = await makeNWSRequest<ForecastResponse>(pointsData.properties.forecast);
if (!forecastData) {
return {
content: [{
type: "text",
text: "Failed to retrieve forecast data",
}],
};
}
// 格式化預報期數據(只顯示未來 5 個期數)
const periods = forecastData.properties?.periods || [];
const formattedForecast = periods.map((period: ForecastPeriod) =>
[
`${period.name || "Unknown"}:`,
`Temperature: ${period.temperature || "Unknown"}°${period.temperatureUnit || "F"}`,
`Wind: ${period.windSpeed || "Unknown"} ${period.windDirection || ""}`,
`${period.shortForecast || "No forecast available"}`,
"---",
].join("\n"),
);
const forecastText = `Forecast for ${latitude}, ${longitude}:\n\n${formattedForecast.join("\n")}`;
return {
content: [{
type: "text",
text: forecastText,
}],
};
},
);
// 運行服務器
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("Weather MCP Server running on stdio");
}
main().catch((error) => {
console.error("Fatal error in main():", error);
process.exit(1);
});
Build Python MCP server
Environment preparation
# 安裝 uv
curl -LsSf https://astral.sh/uv/install.sh | sh
# 創建項目
uv init weather
cd weather
uv venv
source .venv/bin/activate
# 安裝依賴
uv add "mcp[cli]" httpx
from typing import Any
import httpx
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("weather")
NWS_API_BASE = "https://api.weather.gov"
USER_AGENT = "weather-app/1.0"
async def make_nws_request(url: str) -> dict[str, Any] | None:
"""Make a request to the NWS API with proper error handling."""
headers = {"User-Agent": USER_AGENT, "Accept": "application/geo+json"}
async with httpx.AsyncClient() as client:
try:
response = await client.get(url, headers=headers, timeout=30.0)
response.raise_for_status()
return response.json()
except Exception:
return None
@mcp.tool()
async def get_alerts(state: str) -> str:
"""Get weather alerts for a US state."""
url = f"{NWS_API_BASE}/alerts/active/area/{state}"
data = await make_nws_request(url)
if not data or "features" not in data:
return "Unable to fetch alerts or no alerts found."
if not data["features"]:
return f"No active alerts for {state}."
alerts = [format_alert(feature) for feature in data["features"]]
return "\n---\n".join(alerts)
@mcp.tool()
async def get_forecast(latitude: float, longitude: float) -> str:
"""Get weather forecast for a location."""
points_url = f"{NWS_API_BASE}/points/{latitude},{longitude}"
points_data = await make_nws_request(points_url)
if not points_data:
return "Unable to fetch forecast data for this location."
forecast_url = points_data["properties"]["forecast"]
forecast_data = await make_nws_request(forecast_url)
if not forecast_data:
return "Unable to fetch detailed forecast."
periods = forecast_data["properties"]["periods"]
forecasts = []
for period in periods[:5]:
forecast = f"""
{period["name"]}:
Temperature: {period["temperature"]}°{period["temperatureUnit"]}
Wind: {period["windSpeed"]} {period["windDirection"]}
Forecast: {period["detailedForecast"]}
"""
forecasts.append(forecast)
return "\n---\n".join(forecasts)
def format_alert(feature: dict) -> str:
props = feature["properties"]
return f"""
Event: {props.get("event", "Unknown")}
Area: {props.get("areaDesc", "Unknown")}
Severity: {props.get("severity", "Unknown")}
Description: {props.get("description", "No description available")}
Instructions: {props.get("instruction", "No specific instructions provided")}
"""
def main():
mcp.run(transport="stdio")
if __name__ == "__main__":
main()
Production Practice: Deployment Strategy
1. Local development (STDIO mode)
Advantages:
- No network configuration required
- Instant testing and debugging
- Seamless integration with Claude Desktop
Deployment command:
# TypeScript
npm run build
node build/index.js
# Python
uv run weather.py
2. HTTP mode (remote service)
Scenario: Multi-Agent shared services within the organization
Configuration:
{
"mcpServers": {
"company-api": {
"command": "node",
"args": ["/ABSOLUTE/PATH/TO/company-api-server/build/index.js"],
"env": {
"API_KEY": "${COMPANY_API_KEY}"
}
}
}
}
3. Spring Boot integration
Applicable scenarios: Java-heavy enterprise applications
Dependencies:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server</artifactId>
</dependency>
Service Implementation:
@Service
public class WeatherService {
private final RestClient restClient;
public WeatherService() {
this.restClient = RestClient.builder()
.baseUrl("https://api.weather.gov")
.defaultHeader("Accept", "application/geo+json")
.defaultHeader("User-Agent", "WeatherApiClient/1.0")
.build();
}
@Tool(description = "Get weather forecast for a specific latitude/longitude")
public String getWeatherForecastByLocation(
double latitude,
double longitude
) {
// 返回詳細預報數據
}
@Tool(description = "Get weather alerts for a US state")
public String getAlerts(
@ToolParam(description = "Two-letter US state code (e.g. CA, NY)") String state
) {
// 返回活躍警報數據
}
}
Mature Ecosystem: SDK State in 2026
Official SDK library
| Language | SDK Version | GitHub Link | Stability |
|---|---|---|---|
| TypeScript | 1.0.0 | modelcontextprotocol/typescript-sdk | ✅ Production |
| Python | 1.0.0 | modelcontextprotocol/python-sdk | ✅ Production |
| Java | 1.0.0 | modelcontextprotocol/java-sdk | ✅ Production |
| Kotlin | 0.9.0 | modelcontextprotocol/kotlin-sdk | ⚠️ Beta |
| C# | 1.0.0 | modelcontextprotocol/csharp-sdk | ✅ Production |
| Go | 1.0.0 | modelcontextprotocol/go-sdk | ✅ Production |
| Rust | 1.0.0 | modelcontextprotocol/rust-sdk | ✅ Production |
| Swift | 1.0.0 | modelcontextprotocol/swift-sdk | ✅ Production |
| Ruby | 1.0.0 | modelcontextprotocol/ruby-sdk | ✅ Production |
Popular MCP Servers
Statistics (as of March 2026):
| Server | Purpose | GitHub Stars |
|---|---|---|
| filesystem | local file access | 2,500+ |
| github | GitHub API integrations | 1,800+ |
| postgres | PostgreSQL queries | 1,200+ |
| sqlite | SQLite database access | 900+ |
| fetch | HTTP requests | 800+ |
| brave-search | Brave search | 600+ |
Best Practices and Pitfall Guidelines
⚠️ Logging trap: writing to stdout breaks the protocol
Wrong approach (STDIO mode):
# ❌ Bad
print("Processing request") # stdout 會破壞 JSON-RPC
Correct approach:
# ✅ Good (STDIO)
print("Processing request", file=sys.stderr) # stderr 安全
# ✅ Good (Python)
import logging
logging.info("Processing request")
TypeScript version:
// ❌ Bad
console.log("Server started");
// ✅ Good
console.error("Server started"); // stderr 安全
1. Design composability
Principle: Each MCP server focuses on a single responsibility
✅Good:
// 單一職責
name: "stripe-mcp-server",
capabilities: {
tools: ["create_payment", "refund_charge", "list_customers"]
}
❌ Bad:
// 廚房水槽服務器
name: "everything-server",
capabilities: {
tools: ["github_repo", "stripe_payment", "slack_message", "...100 more"]
}
2. Error handling mode
server.registerTool(
"get_data",
{ inputSchema: { ... } },
async (request) => {
try {
const result = await executeTool(request.params);
return {
content: [{ type: "text", text: result }]
};
} catch (error) {
return {
content: [{ type: "text", text: `Error: ${error.message}` }],
isError: true,
};
}
},
);
3. Authentication and Security
Mode 1: OAuth 2.0
const authProvider = {
type: "oauth",
authorizationUrl: "https://github.com/login/oauth/authorize",
tokenUrl: "https://github.com/login/oauth/access_token",
scopes: ["repo", "read:user"],
};
Mode 2: API Key
const apiKeyAuth = {
type: "apiKey",
headerName: "X-API-Key",
};
MCP development trends in 2026
1. Multi-modal support
MCP is being expanded to support:
- 🖼️ Image input/output
- 🎙️ Audio streaming
- 🎥 Video processing
- 📦 Binary data processing
2. Distributed MCP
Emerging models:
- 🔌 Remote MCP server (WebSocket)
- ☁️ Serverless MCP function
- 🏗️ Edge deployment MCP endpoint
- 🌐 Federal MCP Network
3. MCP Market
The platform starts to appear:
- 🔍 Discover MCP servers
- ⭐ Rating and review implementation
- 🚀 One-click deployment
- 💰 Server developer monetization
Decision matrix for selecting MCP
✅ Scenarios where MCP should be used
Scenario 1: Multiple data source integration
- Requires connection to Git, database, API, file system
- AI applications require access to multiple data sources
Scenario 2: Teamwork
- Multiple Agents need to share data sources
- Teams need standardized integration interfaces
Scenario 3: Maintainability
- Avoid maintaining custom connectors for each data source
- MCP server is reusable, testable, and version manageable
❌ Scenarios where MCP should not be used
Scenario 1: Single data source
- Access only one API or database
- MCP protocol overhead > Simplification benefits
Scenario 2: Extreme Performance
- High frequency calls (>1000 QPS)
- Requires custom protocol optimization
Scenario 3: Live Streaming
- Requires extremely low latency (<10ms)
- MCP JSON-RPC overhead may be too high
In-depth analysis: MCP vs other interoperability solutions
Comparison: MCP vs A2A vs REST API
| Dimension | MCP (Model Context Protocol) | A2A (Agent-to-Agent) | REST API + self-built connector |
|---|---|---|---|
| Standardization | High (Open Source Standard) | Medium (Protocol Specification) | Low (Customized) |
| Development Speed | Fast (SDK supported) | Medium (self-built protocol required) | Slow (each data is built from scratch) |
| Maintenance Cost | Low (Unified Protocol) | Medium | High |
| Security | Built-in authentication mechanism | Need to build by yourself | Need to build by yourself |
| Observability | Built-in (JSON-RPC log) | Need to build by yourself | Need to build by yourself |
| Learning Curve | Low (rich official documentation) | Medium | High |
Compensating Tradeoffs: MCP vs REST API
Advantages:
- ✅ Unified protocol, developed once and used in multiple places
- ✅ Built-in protocol negotiation and capability discovery
- ✅ LLM friendly tool calling mode
- ✅ Cross-language support (multiple SDKs)
Disadvantages:
- ❌ JSON-RPC overhead (>100ns/request)
- ❌ Protocol complexity (need to understand JSON-RPC)
- ❌ Rely on LLM trust (requires user approval to call)
Summary: Why MCP is the infrastructure for AI applications in 2026
Core Insights
1. From “Connector” to “Ecosystem”
- MCP is not only a protocol, but also the infrastructure of the AI ecosystem
- The number of connectors changes from “individual implementation” to “ecosystem sharing”
2. From “Model Center” to “Data Center”
- AI capabilities are no longer a limitation
- Data availability becomes a new bottleneck
- MCP solves data accessibility issues
3. From “Tool” to “Agent”
- MCP supports more complex agent mode (multi-Agent collaboration)
- Agents need unified interfaces across data sources and tools
Action recommendations
To Developers:
- Learn MCP immediately (the official documentation is excellent)
- Create the first MCP server (weather API example is easy to get started)
- Convert existing REST API to MCP server
For Business:
- Evaluate MCPization of internal data sources (databases, APIs, file systems)
- Establish MCP server market/registry
- Design internal MCP server security policy
For AI application developers:
- Use MCP SDK (instead of self-built connector)
- Design MCP server (single responsibility, composable)
- Evaluate MCP vs REST API scenarios
Recommended resources
Official Documentation
SDK Library
Popular servers
Learning resources
Summary: MCP represents the architectural transformation of AI applications from “model center” to “data center”. Through unified open standards, developers can quickly build scalable and maintainable AI applications without having to deal with complex integration issues. In 2026, mastering MCP becomes an infrastructure skill for AI application developers.