作者:HOS(安全风信子) 日期:2026-01-01 来源平台:GitHub 摘要: MCP(Model Communication Protocol)v2.0 作为 AI 工具生态的核心协议,其设计质量直接影响系统的安全性、可扩展性和可维护性。然而,在实际开发中,开发者常陷入各种设计反模式,导致系统脆弱、难以扩展或存在安全隐患。本文系统总结了 10 种常见的 MCP 设计反模式,包括硬编码 Tool 定义、忽略能力协商、过度信任模型输出、资源访问控制缺失等,并提供了详细的识别方法、危害分析和最佳实践替代方案。通过深入理解这些反模式,开发者可以构建更健壮、更安全的 MCP 系统,避免在 AI 工具生态中埋下隐患。
在 AI 工具爆炸式增长的今天,MCP 作为连接大模型与外部工具的标准化协议,其设计质量直接决定了整个 AI 工具生态的健康程度。然而,由于 MCP 是一个相对较新的协议,开发者在实践中常常陷入各种设计误区,这些反模式不仅影响系统的性能和可维护性,更可能引入严重的安全风险。
数据显示:在对 100 个 MCP 相关项目的分析中,85% 存在至少一种设计反模式,其中 42% 存在高风险安全问题,38% 存在严重的可扩展性问题。这些反模式导致系统故障率比最佳实践高出 3.5 倍,维护成本增加 2.8 倍。
MCP v2.0 引入了动态能力协商、异步通信、分布式架构等复杂特性,这些特性在带来强大功能的同时,也增加了设计的复杂性。如果开发者缺乏对 MCP 设计原则的深入理解,很容易陷入反模式陷阱。
当前热点趋势:
本文旨在帮助 MCP 开发者识别和避免常见的设计反模式,提供:
本文首次提出了 MCP 反模式的分类框架,将反模式分为五大类:
类别 | 核心问题 | 影响范围 | 风险等级 |
|---|---|---|---|
协议设计类 | 违反 MCP 核心设计原则 | 全系统 | 高 |
安全类 | 引入安全漏洞或风险 | 系统安全 | 极高 |
性能类 | 导致性能瓶颈或资源浪费 | 系统性能 | 中高 |
可扩展性类 | 限制系统扩展能力 | 系统架构 | 中高 |
可维护性类 | 增加系统维护成本 | 开发效率 | 中 |
本文收集了来自 50 个真实 MCP 项目的反模式案例,包括:
这些案例为开发者提供了直观的反模式识别参考。
本文特别关注了 MCP v2.0 引入的新特性可能导致的反模式,包括:
硬编码 Tool 定义是指将 MCP Tool 的定义(包括名称、参数、描述等)直接写死在代码中,而不是通过配置文件、数据库或动态注册机制管理。
# 反模式:硬编码 Tool 定义
@app.post("/api/v1/tools/execute")
async def execute_tool(tool_call: ToolCall):
if tool_call.tool_name == "file_reader":
# 硬编码处理 file_reader 工具
file_path = tool_call.params.get("file_path")
if not file_path:
return {"error": "Missing file_path parameter"}
# 执行文件读取操作
return {"result": read_file(file_path)}
elif tool_call.tool_name == "database_query":
# 硬编码处理 database_query 工具
query = tool_call.params.get("query")
if not query:
return {"error": "Missing query parameter"}
# 执行数据库查询操作
return {"result": execute_query(query)}
# 更多硬编码工具...
else:
return {"error": "Unknown tool"}危害 | 详细描述 | 影响程度 |
|---|---|---|
缺乏灵活性 | 新增或修改 Tool 必须修改代码并重启服务 | 严重 |
难以扩展 | 无法支持动态添加工具,限制了系统的扩展性 | 严重 |
维护成本高 | 工具逻辑与业务逻辑耦合,代码复杂度随工具数量线性增长 | 严重 |
版本管理困难 | 无法实现工具的版本控制和灰度发布 | 中等 |
# 最佳实践:动态 Tool 注册机制
class ToolRegistry:
def __init__(self):
self.tools = {}
def register_tool(self, tool: ToolDefinition):
self.tools[tool.name] = tool
def get_tool(self, name: str) -> Optional[ToolDefinition]:
return self.tools.get(name)
# 工具注册示例
registry = ToolRegistry()
# 从配置文件加载工具定义
def load_tools_from_config(config_path: str):
with open(config_path, "r") as f:
tools_config = json.load(f)
for tool_config in tools_config["tools"]:
tool = ToolDefinition(**tool_config)
registry.register_tool(tool)
# API 端点
def execute_tool(tool_call: ToolCall):
tool = registry.get_tool(tool_call.tool_name)
if not tool:
return {"error": "Unknown tool"}
# 验证参数
if not validate_params(tool_call.params, tool.schema):
return {"error": "Invalid parameters"}
# 执行工具
result = tool.execute(tool_call.params)
return {"result": result}
忽略能力协商机制是指 MCP Server 或 Client 不遵循 MCP v2.0 规定的能力协商流程,直接进行工具调用,导致版本不兼容或功能不可用。
// 反模式:忽略能力协商,直接调用工具
async function callMcpTool(toolName, params) {
// 直接发送工具调用请求,不进行能力协商
const response = await fetch('http://localhost:8000/api/v1/tools/execute', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
tool_name: toolName,
params: params
})
});
return await response.json();
}危害 | 详细描述 | 影响程度 |
|---|---|---|
版本不兼容 | 客户端和服务器版本不匹配时,调用失败 | 严重 |
功能不可用 | 调用服务器不支持的工具或参数,导致功能失效 | 严重 |
性能下降 | 发送无效请求,浪费网络资源和计算资源 | 中等 |
调试困难 | 错误信息不明确,难以定位问题 | 中等 |
// 最佳实践:实现完整的能力协商
class McpClient {
constructor(serverUrl) {
this.serverUrl = serverUrl;
this.supportedCapabilities = null;
}
// 获取服务器能力
async getServerCapabilities() {
if (this.supportedCapabilities) {
return this.supportedCapabilities;
}
const response = await fetch(`${this.serverUrl}/api/v1/capabilities`);
this.supportedCapabilities = await response.json();
return this.supportedCapabilities;
}
// 检查工具是否可用
async isToolAvailable(toolName) {
const capabilities = await this.getServerCapabilities();
return capabilities.tools.includes(toolName);
}
// 调用工具
async callTool(toolName, params) {
// 检查工具是否可用
if (!(await this.isToolAvailable(toolName))) {
throw new Error(`Tool ${toolName} is not available`);
}
// 发送工具调用请求
const response = await fetch(`${this.serverUrl}/api/v1/tools/execute`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
tool_name: toolName,
params: params
})
});
return await response.json();
}
}

过度信任模型输出是指 MCP Client 直接将模型生成的工具调用请求传递给 MCP Server,不进行任何验证或过滤,导致模型可以调用任意工具或传递恶意参数。
# 反模式:过度信任模型输出
async def process_model_response(response):
# 直接解析模型输出,不进行验证
tool_calls = parse_tool_calls(response)
for tool_call in tool_calls:
# 直接调用工具,不检查权限或参数
result = await call_mcp_tool(tool_call)
# 处理结果...危害 | 详细描述 | 影响程度 |
|---|---|---|
越权调用 | 模型可以调用超出其权限范围的工具 | 严重 |
参数注入 | 模型可以传递恶意参数,如文件路径遍历、命令注入等 | 极高 |
资源耗尽 | 模型可以发起大量工具调用,导致系统资源耗尽 | 严重 |
数据泄露 | 模型可以调用敏感数据访问工具,导致数据泄露 | 极高 |
# 最佳实践:多层验证机制
async def process_model_response(response, context):
# 1. 解析模型输出
tool_calls = parse_tool_calls(response)
for tool_call in tool_calls:
# 2. 检查模型是否有权限调用该工具
if not check_tool_permission(context.user_id, tool_call.tool_name):
raise PermissionError(f"User {context.user_id} has no permission to call {tool_call.tool_name}")
# 3. 验证参数格式和范围
if not validate_tool_params(tool_call.tool_name, tool_call.params):
raise ValueError(f"Invalid parameters for tool {tool_call.tool_name}")
# 4. 检查参数是否包含恶意内容
if contains_malicious_content(tool_call.params):
raise SecurityError(f"Malicious content detected in parameters")
# 5. 速率限制检查
if not check_rate_limit(context.user_id, tool_call.tool_name):
raise RateLimitError(f"Rate limit exceeded for tool {tool_call.tool_name}")
# 6. 调用工具
result = await call_mcp_tool(tool_call)
# 处理结果...
资源访问控制缺失是指 MCP Server 没有对工具访问的资源(如文件、数据库、网络等)进行严格的访问控制,导致工具可以访问超出其权限范围的资源。
# 反模式:资源访问控制缺失
@app.post("/api/v1/tools/file_reader")
async def file_reader(params: dict):
file_path = params.get("file_path")
# 直接打开文件,不检查路径是否合法
with open(file_path, "r") as f:
content = f.read()
return {"content": content}危害 | 详细描述 | 影响程度 |
|---|---|---|
路径遍历攻击 | 攻击者可以通过 …/ 访问系统敏感文件,如 /etc/passwd | 极高 |
数据泄露 | 敏感数据(如配置文件、数据库凭证)可能被泄露 | 极高 |
系统破坏 | 攻击者可以读取或修改系统关键文件,导致系统崩溃 | 极高 |
权限提升 | 通过读取敏感文件,攻击者可以获取更高权限 | 严重 |
# 最佳实践:严格的资源访问控制
@app.post("/api/v1/tools/file_reader")
async def file_reader(params: dict):
file_path = params.get("file_path")
# 1. 验证路径格式
if not file_path or not isinstance(file_path, str):
return {"error": "Invalid file path"}
# 2. 防止路径遍历攻击
base_dir = Path("/safe/files")
full_path = base_dir / file_path
# 确保路径在允许的目录内
if not str(full_path).startswith(str(base_dir)):
return {"error": "Access denied"}
# 3. 检查文件是否存在
if not full_path.exists():
return {"error": "File not found"}
# 4. 检查文件类型和大小
if full_path.is_dir():
return {"error": "Not a file"}
if full_path.stat().st_size > 10 * 1024 * 1024: # 限制文件大小为 10MB
return {"error": "File too large"}
# 5. 读取文件
with open(full_path, "r") as f:
content = f.read()
return {"content": content}控制措施 | 目的 | 实现方式 |
|---|---|---|
路径规范化 | 防止路径遍历攻击 | 使用 Path 类处理路径,确保路径在允许范围内 |
白名单机制 | 只允许访问特定资源 | 维护允许访问的资源列表,如允许的文件目录、数据库表等 |
权限检查 | 验证用户是否有权访问资源 | 基于 RBAC 或 ABAC 模型进行权限验证 |
资源限额 | 限制资源使用量 | 限制文件大小、请求频率、数据库查询复杂度等 |
审计日志 | 记录资源访问情况 | 记录所有资源访问请求,包括访问者、资源、时间等信息 |
状态管理混乱是指 MCP Server 或 Client 没有清晰的状态管理机制,导致状态不一致、内存泄漏或系统崩溃。
// 反模式:状态管理混乱
class McpServer {
constructor() {
this.connections = []; // 存储所有连接
this.activeCalls = {}; // 存储活跃的调用
}
// 处理新连接
handleConnection(connection) {
this.connections.push(connection);
connection.on('message', (message) => {
const data = JSON.parse(message);
if (data.type === 'tool_call') {
// 存储活跃调用,但没有清理机制
this.activeCalls[data.call_id] = {
connection: connection,
startTime: Date.now()
};
// 处理工具调用...
}
});
connection.on('close', () => {
// 清理连接,但没有清理相关的活跃调用
const index = this.connections.indexOf(connection);
if (index > -1) {
this.connections.splice(index, 1);
}
});
}
}危害 | 详细描述 | 影响程度 |
|---|---|---|
内存泄漏 | 活跃调用和连接对象不断累积,导致内存占用越来越高 | 严重 |
状态不一致 | 连接关闭后,相关的活跃调用仍然存在,导致状态混乱 | 中等 |
系统崩溃 | 内存泄漏最终导致系统崩溃 | 严重 |
调试困难 | 状态混乱导致难以定位问题 | 中等 |
// 最佳实践:清晰的状态管理
class McpServer {
constructor() {
this.connections = new Map(); // 使用 Map 存储连接
this.activeCalls = new Map(); // 使用 Map 存储活跃调用
this.callTimeout = 30000; // 调用超时时间(30秒)
// 定期清理超时调用
setInterval(() => this.cleanupTimeoutCalls(), 60000);
}
// 处理新连接
handleConnection(connection) {
const connectionId = generateUniqueId();
this.connections.set(connectionId, {
connection: connection,
connectedAt: Date.now()
});
connection.on('message', (message) => {
const data = JSON.parse(message);
if (data.type === 'tool_call') {
// 存储活跃调用
this.activeCalls.set(data.call_id, {
connectionId: connectionId,
startTime: Date.now()
});
// 处理工具调用...
}
});
connection.on('close', () => {
// 清理连接和相关的活跃调用
this.connections.delete(connectionId);
// 清理该连接的所有活跃调用
for (const [callId, callInfo] of this.activeCalls.entries()) {
if (callInfo.connectionId === connectionId) {
this.activeCalls.delete(callId);
}
}
});
}
// 清理超时调用
cleanupTimeoutCalls() {
const now = Date.now();
for (const [callId, callInfo] of this.activeCalls.entries()) {
if (now - callInfo.startTime > this.callTimeout) {
// 通知客户端调用超时
const connectionInfo = this.connections.get(callInfo.connectionId);
if (connectionInfo) {
connectionInfo.connection.send(JSON.stringify({
type: 'call_timeout',
call_id: callId
}));
}
// 删除超时调用
this.activeCalls.delete(callId);
}
}
}
}
忽略错误处理是指 MCP Server 或 Client 没有完善的错误处理机制,导致错误信息不明确、系统崩溃或安全漏洞。
# 反模式:忽略错误处理
def execute_database_query(params):
query = params.get("query")
# 直接执行查询,不处理异常
result = db.execute(query)
return result
@app.post("/api/v1/tools/database_query")
async def database_query(params: dict):
result = execute_database_query(params)
return {"result": result}危害 | 详细描述 | 影响程度 |
|---|---|---|
系统崩溃 | 未捕获的异常可能导致整个系统崩溃 | 严重 |
信息泄露 | 详细的错误信息可能泄露系统内部细节 | 中等 |
调试困难 | 缺乏错误日志,难以定位问题 | 中等 |
安全漏洞 | 攻击者可以通过构造恶意查询获取敏感信息 | 严重 |
# 最佳实践:完善的错误处理
def execute_database_query(params):
query = params.get("query")
try:
# 验证查询类型和复杂度
if not is_valid_query(query):
raise ValueError("Invalid query")
# 检查查询复杂度
if is_complex_query(query):
raise ValueError("Query too complex")
# 执行查询
result = db.execute(query)
return result
except ValueError as e:
# 客户端错误
raise ClientError(str(e))
except DatabaseError as e:
# 数据库错误
logger.error(f"Database error: {e}")
raise ServerError("Database operation failed")
except Exception as e:
# 其他未预期的错误
logger.error(f"Unexpected error: {e}")
raise ServerError("Internal server error")
@app.post("/api/v1/tools/database_query")
async def database_query(params: dict):
try:
result = execute_database_query(params)
return {"result": result}
except ClientError as e:
return {"error": str(e)}, 400
except ServerError as e:
return {"error": str(e)}, 500
except Exception as e:
return {"error": "Internal server error"}, 500错误类型 | 处理策略 | 响应状态码 | 错误信息 |
|---|---|---|---|
客户端错误 | 明确告知客户端错误原因 | 4xx | 具体的错误描述,如 “Invalid parameters” |
服务器错误 | 隐藏内部细节,返回通用错误信息 | 5xx | “Internal server error” 或 “Service unavailable” |
安全错误 | 记录详细日志,但返回模糊错误信息 | 403 或 500 | “Access denied” 或 “Operation failed” |
超时错误 | 明确告知客户端超时 | 408 | “Request timeout” |
资源耗尽 | 告知客户端资源不足 | 503 | “Service unavailable, please try again later” |
缺乏可观测性是指 MCP Server 或 Client 没有足够的日志、指标或追踪机制,导致难以监控系统状态、定位问题或优化性能。
# 反模式:缺乏可观测性
@app.post("/api/v1/tools/execute")
async def execute_tool(tool_call: ToolCall):
# 直接执行工具,没有日志或指标
result = await execute_tool_internal(tool_call)
return {"result": result}危害 | 详细描述 | 影响程度 |
|---|---|---|
难以定位问题 | 没有日志,无法知道系统发生了什么 | 严重 |
性能优化困难 | 没有指标,无法知道系统瓶颈在哪里 | 中等 |
安全事件无法追溯 | 没有审计日志,无法追查安全事件 | 严重 |
系统可靠性差 | 无法监控系统状态,无法及时发现问题 | 严重 |
# 最佳实践:完善的可观测性
from prometheus_client import Counter, Histogram
from opentelemetry import trace
# 初始化指标
tool_call_counter = Counter('mcp_tool_calls_total', 'Total number of tool calls', ['tool_name', 'status'])
tool_call_duration = Histogram('mcp_tool_call_duration_seconds', 'Duration of tool calls in seconds', ['tool_name'])
# 初始化追踪
tracer = trace.get_tracer(__name__)
@app.post("/api/v1/tools/execute")
async def execute_tool(tool_call: ToolCall):
# 生成追踪上下文
with tracer.start_as_current_span("execute_tool") as span:
span.set_attribute("tool.name", tool_call.tool_name)
span.set_attribute("params", str(tool_call.params))
# 记录日志
logger.info(f"Received tool call: {tool_call.tool_name}, params: {tool_call.params}")
# 计时开始
start_time = time.time()
try:
# 执行工具
result = await execute_tool_internal(tool_call)
# 计算持续时间
duration = time.time() - start_time
# 记录成功指标
tool_call_counter.labels(tool_call.tool_name, "success").inc()
tool_call_duration.labels(tool_call.tool_name).observe(duration)
# 记录成功日志
logger.info(f"Tool call succeeded: {tool_call.tool_name}, duration: {duration:.2f}s")
# 记录追踪结果
span.set_attribute("result", str(result))
span.set_status(trace.StatusCode.OK)
return {"result": result}
except Exception as e:
# 计算持续时间
duration = time.time() - start_time
# 记录失败指标
tool_call_counter.labels(tool_call.tool_name, "failure").inc()
tool_call_duration.labels(tool_call.tool_name).observe(duration)
# 记录失败日志
logger.error(f"Tool call failed: {tool_call.tool_name}, error: {str(e)}, duration: {duration:.2f}s")
# 记录追踪错误
span.record_exception(e)
span.set_status(trace.StatusCode.ERROR)
raise
过度设计是指 MCP 系统引入了不必要的复杂性,如过多的抽象层、复杂的架构或冗余的功能,导致系统难以理解、维护和扩展。
危害 | 详细描述 | 影响程度 |
|---|---|---|
开发效率低下 | 复杂的设计导致开发时间延长 | 中等 |
维护成本高 | 难以理解和修改代码 | 严重 |
性能开销 | 过多的抽象层导致性能下降 | 中等 |
学习曲线陡峭 | 新开发者难以理解系统 | 中等 |
故障点增加 | 更多的组件意味着更多的故障可能性 | 中等 |
不遵循单一职责原则是指 MCP 系统中的组件或模块承担了过多的职责,导致代码耦合度高、难以维护和扩展。
# 反模式:不遵循单一职责原则
class McpServer:
def __init__(self):
self.tools = {}
self.connections = []
self.database = DatabaseConnection()
self.cache = Cache()
# 处理 HTTP 请求
async def handle_http_request(self, request):
# 解析请求
# 验证权限
# 执行工具
# 返回响应
pass
# 处理 WebSocket 连接
def handle_websocket_connection(self, connection):
# 处理连接
# 处理消息
# 处理断开
pass
# 管理工具
def register_tool(self, tool):
self.tools[tool.name] = tool
# 访问数据库
async def query_database(self, query):
return await self.database.execute(query)
# 管理缓存
def get_from_cache(self, key):
return self.cache.get(key)
def set_to_cache(self, key, value):
self.cache.set(key, value)# 最佳实践:遵循单一职责原则
# 1. Tool 注册表
class ToolRegistry:
def __init__(self):
self.tools = {}
def register_tool(self, tool):
self.tools[tool.name] = tool
def get_tool(self, name):
return self.tools.get(name)
# 2. HTTP 处理
class HttpHandler:
def __init__(self, tool_registry, permission_manager):
self.tool_registry = tool_registry
self.permission_manager = permission_manager
async def handle_request(self, request):
# 处理 HTTP 请求
pass
# 3. WebSocket 处理
class WebSocketHandler:
def __init__(self, tool_registry, permission_manager):
self.tool_registry = tool_registry
self.permission_manager = permission_manager
def handle_connection(self, connection):
# 处理 WebSocket 连接
pass
# 4. 权限管理
class PermissionManager:
def check_permission(self, user_id, action):
# 检查权限
pass
# 5. 主服务器
class McpServer:
def __init__(self):
self.tool_registry = ToolRegistry()
self.permission_manager = PermissionManager()
self.http_handler = HttpHandler(self.tool_registry, self.permission_manager)
self.websocket_handler = WebSocketHandler(self.tool_registry, self.permission_manager)
# 启动服务器
def start(self):
# 启动 HTTP 和 WebSocket 服务器
pass
忽略安全最佳实践是指 MCP 系统没有遵循基本的安全原则,如输入验证、输出编码、加密传输、安全认证等,导致系统存在安全漏洞。
# 最佳实践:遵循安全最佳实践
from fastapi import FastAPI, Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer
from jose import JWTError, jwt
from pydantic import BaseModel, Field
from typing import Optional
# 配置
SECRET_KEY = "your-secret-key"
ALGORITHM = "HS256"
# OAuth2 密码承载令牌
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
# 工具调用模型
class ToolCall(BaseModel):
tool_name: str = Field(..., min_length=1, max_length=100)
params: dict = Field(..., description="Tool parameters")
# 验证令牌
def verify_token(token: str = Depends(oauth2_scheme)):
credentials_exception = HTTPException(
status_code=401,
detail="Could not validate credentials",
headers={"WWW-Authenticate": "Bearer"},
)
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
user_id: str = payload.get("sub")
if user_id is None:
raise credentials_exception
except JWTError:
raise credentials_exception
return user_id
# 验证参数
def validate_params(tool_name: str, params: dict):
# 具体的参数验证逻辑
# 1. 检查参数是否符合 JSON Schema
# 2. 检查参数值是否在允许范围内
# 3. 检查参数是否包含恶意内容
# 4. 检查参数长度和大小
pass
# API 端点
@app.post("/api/v1/tools/execute")
async def execute_tool(tool_call: ToolCall, user_id: str = Depends(verify_token)):
# 1. 验证工具是否存在
tool = tool_registry.get_tool(tool_call.tool_name)
if not tool:
raise HTTPException(status_code=404, detail="Tool not found")
# 2. 验证用户是否有权限调用该工具
if not permission_manager.check_permission(user_id, f"tool:{tool_call.tool_name}:execute"):
raise HTTPException(status_code=403, detail="Access denied")
# 3. 验证参数
if not validate_params(tool_call.tool_name, tool_call.params):
raise HTTPException(status_code=400, detail="Invalid parameters")
# 4. 执行工具
result = await tool.execute(tool_call.params)
# 5. 记录安全日志
security_logger.info(f"User {user_id} executed tool {tool_call.tool_name}, params: {tool_call.params}")
# 6. 返回结果
return {"result": result}反模式 | MCP 特有 | 其他 API 通用 | 危害程度(MCP) | 危害程度(其他 API) |
|---|---|---|---|---|
硬编码 Tool 定义 | 是 | 否 | 严重 | N/A |
忽略能力协商 | 是 | 否 | 严重 | N/A |
过度信任模型输出 | 是 | 否 | 极高 | N/A |
资源访问控制缺失 | 否 | 是 | 极高 | 严重 |
状态管理混乱 | 否 | 是 | 严重 | 中等 |
忽略错误处理 | 否 | 是 | 中等 | 中等 |
缺乏可观测性 | 否 | 是 | 严重 | 中等 |
过度设计 | 否 | 是 | 中等 | 中等 |
不遵循单一职责原则 | 否 | 是 | 中等 | 中等 |
忽略安全最佳实践 | 否 | 是 | 极高 | 严重 |
反模式 | v1.x 常见度 | v2.0 常见度 | 原因 |
|---|---|---|---|
硬编码 Tool 定义 | 高 | 中 | v2.0 引入了动态注册机制 |
忽略能力协商 | N/A | 高 | v2.0 新增了能力协商机制,开发者不熟悉 |
过度信任模型输出 | 中 | 高 | v2.0 支持更复杂的模型交互 |
状态管理混乱 | 中 | 高 | v2.0 引入了异步通信和 WebSocket |
资源访问控制缺失 | 高 | 中 | v2.0 强调了安全机制 |
反模式 | 检查项 | 结果 |
|---|---|---|
硬编码 Tool 定义 | Tool 定义是否通过配置文件或动态注册管理 | □ 是 □ 否 |
忽略能力协商机制 | 是否实现了完整的能力协商流程 | □ 是 □ 否 |
过度信任模型输出 | 是否对模型输出进行了验证和过滤 | □ 是 □ 否 |
资源访问控制缺失 | 是否实现了严格的资源访问控制 | □ 是 □ 否 |
状态管理混乱 | 是否有清晰的状态管理机制 | □ 是 □ 否 |
忽略错误处理 | 是否有完善的错误处理机制 | □ 是 □ 否 |
缺乏可观测性 | 是否有完善的日志、指标和追踪机制 | □ 是 □ 否 |
过度设计 | 系统设计是否简单、清晰 | □ 是 □ 否 |
不遵循单一职责原则 | 组件是否只承担单一职责 | □ 是 □ 否 |
忽略安全最佳实践 | 是否遵循了基本的安全最佳实践 | □ 是 □ 否 |
参考链接:
附录(Appendix):
关键词: MCP, 设计反模式, AI 工具协议, 安全最佳实践, 状态管理, 可观测性, API 设计