MCP 協議入門:讓 AI 連接外部世界
介紹 Anthropic 的 Model Context Protocol,教你開發 MCP Server 讓 Claude 能存取資料庫、API 等外部資源。
AI Academy 編輯部2025年11月27日
MCP 協議入門:讓 AI 連接外部世界
什麼是 MCP?
MCP(Model Context Protocol)是 Anthropic 推出的開放協議,讓 AI 模型能安全地與外部系統互動。透過 MCP,Claude 可以存取資料庫、呼叫 API、讀取檔案等,大幅擴展其能力。
MCP 架構
┌─────────────┐ MCP 協議 ┌─────────────────┐
│ Claude │ ←─────────────→ │ MCP Server │
│ (Client) │ │ (你開發的服務) │
└─────────────┘ └────────┬────────┘
│
▼
┌─────────────────┐
│ 外部資源 │
│ (DB、API、檔案) │
└─────────────────┘
MCP 的優勢
| 特點 | 說明 |
|---|---|
| 標準化 | 統一的協議,一次開發多處使用 |
| 安全 | 明確的權限控制 |
| 模組化 | 每個 Server 專注一個功能 |
| 開放 | 開源協議,社群共建 |
核心概念
MCP Server 可以提供三種類型的功能:
1. Tools(工具)
讓 AI 執行操作:
- 查詢資料庫
- 發送郵件
- 呼叫外部 API
- 執行程式碼
2. Resources(資源)
提供資料給 AI 讀取:
- 檔案內容
- 資料庫記錄
- API 回應
- 系統狀態
3. Prompts(提示模板)
預設的提示範本:
- 程式碼審查模板
- 文件撰寫模板
- 分析報告模板
快速開始:建立第一個 MCP Server
1. 環境準備
# 安裝 MCP SDK
pip install mcp
2. 建立簡單的天氣查詢 Server
# weather_server.py
from mcp.server import Server
from mcp.types import Tool, TextContent
import httpx
# 建立 Server 實例
server = Server("weather-server")
@server.list_tools()
async def list_tools():
"""列出可用的工具"""
return [
Tool(
name="get_weather",
description="查詢指定城市的天氣",
inputSchema={
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名稱,例如:Taipei"
}
},
"required": ["city"]
}
)
]
@server.call_tool()
async def call_tool(name: str, arguments: dict):
"""執行工具"""
if name == "get_weather":
city = arguments["city"]
# 呼叫天氣 API(這裡用模擬資料)
weather_data = {
"Taipei": {"temp": 28, "condition": "晴天"},
"Tokyo": {"temp": 22, "condition": "多雲"},
"New York": {"temp": 15, "condition": "下雨"},
}
if city in weather_data:
data = weather_data[city]
return [TextContent(
type="text",
text=f"{city} 目前天氣:{data['condition']},氣溫 {data['temp']}°C"
)]
else:
return [TextContent(
type="text",
text=f"找不到 {city} 的天氣資料"
)]
raise ValueError(f"Unknown tool: {name}")
# 啟動 Server
if __name__ == "__main__":
import asyncio
from mcp.server.stdio import stdio_server
asyncio.run(stdio_server(server))
3. 設定 Claude Desktop
在 Claude Desktop 設定檔加入 MCP Server:
// macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
// Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"weather": {
"command": "python",
"args": ["/path/to/weather_server.py"]
}
}
}
4. 使用
重啟 Claude Desktop 後,你可以直接問:
「台北現在天氣如何?」
Claude 會自動呼叫你的 MCP Server 來取得天氣資訊。
實用範例:資料庫查詢 Server
# db_server.py
from mcp.server import Server
from mcp.types import Tool, TextContent, Resource
import sqlite3
server = Server("database-server")
# 資料庫連線
def get_db():
return sqlite3.connect("app.db")
@server.list_tools()
async def list_tools():
return [
Tool(
name="query_users",
description="查詢用戶資料",
inputSchema={
"type": "object",
"properties": {
"email": {
"type": "string",
"description": "用戶 email(可選)"
},
"limit": {
"type": "integer",
"description": "回傳筆數限制",
"default": 10
}
}
}
),
Tool(
name="count_users",
description="統計用戶數量",
inputSchema={
"type": "object",
"properties": {}
}
)
]
@server.call_tool()
async def call_tool(name: str, arguments: dict):
db = get_db()
cursor = db.cursor()
try:
if name == "query_users":
email = arguments.get("email")
limit = arguments.get("limit", 10)
if email:
cursor.execute(
"SELECT id, name, email FROM users WHERE email = ? LIMIT ?",
(email, limit)
)
else:
cursor.execute(
"SELECT id, name, email FROM users LIMIT ?",
(limit,)
)
rows = cursor.fetchall()
result = "\n".join([f"ID: {r[0]}, Name: {r[1]}, Email: {r[2]}" for r in rows])
return [TextContent(type="text", text=result or "沒有找到用戶")]
elif name == "count_users":
cursor.execute("SELECT COUNT(*) FROM users")
count = cursor.fetchone()[0]
return [TextContent(type="text", text=f"目前共有 {count} 位用戶")]
finally:
db.close()
raise ValueError(f"Unknown tool: {name}")
提供 Resources
讓 Claude 能讀取檔案或資料:
@server.list_resources()
async def list_resources():
"""列出可用資源"""
return [
Resource(
uri="config://app",
name="應用程式設定",
description="應用程式的設定檔內容",
mimeType="application/json"
)
]
@server.read_resource()
async def read_resource(uri: str):
"""讀取資源內容"""
if uri == "config://app":
with open("config.json", "r") as f:
return f.read()
raise ValueError(f"Unknown resource: {uri}")
常用 MCP Servers
社群已經開發了許多實用的 MCP Server:
| Server | 功能 |
|---|---|
| mcp-server-sqlite | SQLite 資料庫操作 |
| mcp-server-filesystem | 檔案系統存取 |
| mcp-server-github | GitHub API 整合 |
| mcp-server-slack | Slack 訊息發送 |
| mcp-server-puppeteer | 網頁自動化 |
安裝社群 Server
# 使用 npx 安裝
npx @anthropic/mcp-server-sqlite --db-path ./my-database.db
設定多個 Server
{
"mcpServers": {
"sqlite": {
"command": "npx",
"args": ["@anthropic/mcp-server-sqlite", "--db-path", "./app.db"]
},
"filesystem": {
"command": "npx",
"args": ["@anthropic/mcp-server-filesystem", "--root", "./documents"]
},
"weather": {
"command": "python",
"args": ["./my-servers/weather_server.py"]
}
}
}
安全考量
1. 權限控制
# 限制可存取的目錄
ALLOWED_PATHS = ["/data", "/uploads"]
def is_path_allowed(path: str) -> bool:
return any(path.startswith(p) for p in ALLOWED_PATHS)
2. 輸入驗證
@server.call_tool()
async def call_tool(name: str, arguments: dict):
# 驗證輸入
if name == "query_db":
query = arguments.get("query", "")
# 防止 SQL Injection
if any(keyword in query.upper() for keyword in ["DROP", "DELETE", "UPDATE"]):
return [TextContent(type="text", text="不允許的操作")]
3. 資源限制
import asyncio
@server.call_tool()
async def call_tool(name: str, arguments: dict):
# 設定超時
try:
result = await asyncio.wait_for(
do_operation(arguments),
timeout=30.0
)
return result
except asyncio.TimeoutError:
return [TextContent(type="text", text="操作超時")]
Debug 技巧
查看 Server 日誌
import logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
@server.call_tool()
async def call_tool(name: str, arguments: dict):
logger.debug(f"Tool called: {name} with {arguments}")
# ...
測試 Server
# test_server.py
import asyncio
from weather_server import server
async def test():
# 測試列出工具
tools = await server.list_tools()
print("Available tools:", tools)
# 測試呼叫工具
result = await server.call_tool("get_weather", {"city": "Taipei"})
print("Result:", result)
asyncio.run(test())
總結
MCP 讓 Claude 能安全地與外部系統互動:
- Tools:執行操作(查詢、發送、計算)
- Resources:提供資料(檔案、設定)
- Prompts:預設模板
下一步行動:
- 安裝 Claude Desktop 並設定 MCP
- 嘗試使用社群的 MCP Server
- 開發自己的第一個 MCP Server
- 整合到你的工作流程中
相關文章:
參考資源: