🧩 1. MCP 是什么
Model Context Protocol(MCP)是 Anthropic 于 2024 年提出的开放标准协议,定义了 AI 模型与外部工具/数据源之间的标准通信接口。
在 MCP 出现之前,每个 AI 框架都有自己的工具接入方式,工具提供方需要为不同框架分别开发适配层。MCP 的目标是成为 AI 工具生态的"USB 接口"——一次开发,到处接入。
为什么需要 MCP
❌ MCP 之前(碎片化)
Claude
GPT
Hermes
→ 自定义格式 →工具 A(适配1)
→ 自定义格式 →工具 A(适配2)
→ 自定义格式 →工具 A(适配3)
重复开发,无法复用
VS
✅ MCP 之后(标准化)
Claude
GPT
Hermes
↓ MCP 标准协议
MCP Server A
→
工具 A(复用)
一次开发,到处接入
🔍 生态价值:MCP 的真正价值在于生态效应。当越来越多的工具提供方实现 MCP Server,所有支持 MCP 的 Agent 都能直接接入,形成正向循环。目前已有 GitHub、Slack、Google Drive、PostgreSQL 等数百个官方和社区 MCP Server。
📡 2. 协议通信机制
传输层
MCP 支持两种传输方式:
- stdio(标准输入输出):最常用。Host 启动 MCP Server 进程,通过 stdin/stdout 通信。适合本地工具。
- HTTP + SSE:Server 以 HTTP 服务形式运行,通过 Server-Sent Events 推送消息。适合远程服务或需要持久化连接的场景。
💡 Hermes 使用 stdio 模式:Hermes 在配置 MCP Server 时,通过
command 和 args 字段启动 Server 进程,使用 stdio 通信。这意味着每次 Hermes 启动时,MCP Server 进程也会随之启动。消息格式(JSON-RPC 2.0)
MCP 基于 JSON-RPC 2.0 协议,所有消息都是 JSON 格式:
bash
// 1. Host 向 Server 发送工具调用请求
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_stock_price",
"arguments": { "symbol": "600519" }
}
}
// 2. Server 返回结果
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [{ "type": "text", "text": "贵州茅台(600519): ¥1,680.00 (+2.3%)" }]
}
}
MCP Server 能力类型
- Tools:可被模型调用的函数,有输入参数和返回值(最常用)
- Resources:可读取的数据资源,如文件、数据库记录
- Prompts:预定义的提示模板,可被 Host 调用
🔗 3. 接入现有 MCP Server
社区已有大量成熟的 MCP Server,直接接入即可扩展 Hermes 的能力:
📁 文件系统
读写本地文件和目录,支持权限控制
@modelcontextprotocol/server-filesystem
🐙 GitHub
操作仓库、Issue、PR、代码搜索
@modelcontextprotocol/server-github
🗄️ PostgreSQL
查询数据库,自动获取 Schema 信息
@modelcontextprotocol/server-postgres
🔍 Brave Search
通过 Brave Search API 进行网络搜索
@modelcontextprotocol/server-brave-search
☸️ Kubernetes
管理 K8s 集群、Pod、Service、Deployment
@modelcontextprotocol/server-kubernetes
🌐 Puppeteer
控制浏览器,截图、填表、自动化操作
@modelcontextprotocol/server-puppeteer
在 Hermes 中配置 MCP Server
yaml
# ~/.hermes/config.yaml
mcp_servers:
# GitHub:需要 Personal Access Token
github:
command: npx
args: ["-y", "@modelcontextprotocol/server-github"]
env:
GITHUB_PERSONAL_ACCESS_TOKEN: "${GITHUB_TOKEN}"
# PostgreSQL:连接字符串
postgres:
command: npx
args: ["-y", "@modelcontextprotocol/server-postgres",
"postgresql://user:pass@localhost/mydb"]
# 文件系统:限制访问目录
filesystem:
command: npx
args: ["-y", "@modelcontextprotocol/server-filesystem",
"/home/user/documents"] # 只允许访问此目录
⚠️ 安全注意:MCP Server 的权限即 Agent 的权限。配置 PostgreSQL MCP Server 时,建议使用只读账号;配置文件系统 MCP Server 时,严格限制可访问的目录范围。
🛠️ 4. 开发自定义 MCP Server
当现有 MCP Server 无法满足需求时,可以自己开发。以开发一个"A股实时行情查询"MCP Server 为例:
TypeScript 实现
typescript
// stock-mcp-server/src/index.ts
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
const server = new Server(
{ name: "stock-server", version: "1.0.0" },
{ capabilities: { tools: {} } }
);
// 声明工具列表(模型会看到这些定义)
server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [{
name: "get_stock_price",
description: "查询A股实时行情,输入股票代码返回最新价格和涨跌幅",
inputSchema: {
type: "object",
properties: {
symbol: { type: "string", description: "股票代码,如 600519" }
},
required: ["symbol"]
}
}]
}));
// 处理工具调用
server.setRequestHandler(CallToolRequestSchema, async (request) => {
if (request.params.name === "get_stock_price") {
const { symbol } = request.params.arguments as { symbol: string };
// 调用行情 API(示例)
const price = await fetchStockPrice(symbol);
return {
content: [{ type: "text", text: `${symbol}: ¥${price.current} (${price.change}%)` }]
};
}
throw new Error(`Unknown tool: ${request.params.name}`);
});
// 启动 stdio 传输
const transport = new StdioServerTransport();
await server.connect(transport);
Python 实现
typescript
# stock_mcp_server.py
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent
app = Server("stock-server")
@app.list_tools()
async def list_tools():
return [
Tool(
name="get_stock_price",
description="查询A股实时行情",
inputSchema={
"type": "object",
"properties": {
"symbol": {"type": "string", "description": "股票代码"}
},
"required": ["symbol"]
}
)
]
@app.call_tool()
async def call_tool(name: str, arguments: dict):
if name == "get_stock_price":
symbol = arguments["symbol"]
price = await fetch_stock_price(symbol) # 你的行情获取逻辑
return [TextContent(type="text", text=f"{symbol}: ¥{price}")]
async def main():
async with stdio_server() as (read_stream, write_stream):
await app.run(read_stream, write_stream, app.create_initialization_options())
在 Hermes 中接入自定义 Server
yaml
# ~/.hermes/config.yaml
mcp_servers:
stock:
command: node
args: ["/path/to/stock-mcp-server/dist/index.js"]
# Python 版本:
# command: python3
# args: ["/path/to/stock_mcp_server.py"]
🔍 5. 调试与排错
使用 MCP Inspector 调试
官方提供了 MCP Inspector 工具,可以在浏览器中直接测试 MCP Server:
bash
npx @modelcontextprotocol/inspector node dist/index.js
# 打开 http://localhost:5173 进行可视化调试
常见问题
- Server 启动失败:检查
command和args是否正确,手动在终端运行命令验证 - 工具未出现在 Agent 中:检查
list_tools返回格式是否符合 MCP 规范 - 工具调用返回错误:在 Server 中添加详细日志(输出到 stderr,不影响 stdio 通信)
- 环境变量未生效:MCP Server 进程的环境变量需要在
env字段中显式传入
💡 调试技巧:MCP Server 的日志必须输出到 stderr,不能输出到 stdout。stdout 是 JSON-RPC 通信通道,任何非 JSON 输出都会导致协议解析失败。