【MCP 全栈教程】第 35 篇:MCP 性能优化与生产部署
本系列定位:从协议原理到 Server 开发、Client 开发、再到各大平台实战集成,系统化掌握 MCP(Model Context Protocol)全栈技术体系。
本篇你将学到
- 掌握 STDIO Server 的进程启动优化,通过延迟加载工具显著降低冷启动时间
- 学会 HTTP Server 的连接池与并发控制配置
- 建立工具调用的超时与熔断策略,防止级联故障
- 运用 capabilities 缓存减少
discover阶段的开销 - 掌握 SSE 连接的保活与重连机制
- 设计生产级监控指标体系(P99 延迟、错误率、工具调用频率)
一句话总结:生产环境的 MCP 系统需要在"启动快、调用稳、连接不断、可观测"四个维度同时发力,本篇提供每个维度的落地配置与代码模板。
一、STDIO 进程启动优化
1.1 冷启动问题
STDIO 传输模式下,Host 每次连接都会 fork 一个新的 Server 子进程。如果 Server 启动时加载了大量工具定义、初始化了重型依赖,用户会感受到明显延迟:
| 启动阶段 | 典型耗时 | 优化空间 |
|---|---|---|
| Python 解释器启动 | 50-100ms | 改用 PyInstaller 单文件打包 |
| 依赖导入(pandas、torch 等) | 500-3000ms | 延迟加载 |
| 工具定义注册 | 50-200ms | 按需注册 |
| 数据库连接池初始化 | 100-500ms | 懒初始化 |
| 鉴权预处理 | 50-100ms | 移到首次请求时 |
1.2 延迟加载工具模式
核心思路:Server 启动时只注册一个"轻量骨架",真正的工具实现按需加载。
Python 实现:
import importlib
from typing import Any, Callable
class LazyToolRegistry:
"""延迟加载工具注册表。"""
def __init__(self):
self._definitions: dict[str, dict] = {} # 工具定义(轻量)
self._loaders: dict[str, Callable] = {} # 加载函数(延迟)
self._impls: dict[str, Any] = {} # 已加载的实现(缓存)
def register_lazy(
self,
name: str,
definition: dict,
loader: Callable[[], Any],
):
"""注册工具定义和延迟加载器,但不立即执行 loader。"""
self._definitions[name] = definition
self._loaders[name] = loader
def list_tools(self) -> list[dict]:
"""tools/list 立即返回,无需加载实现。"""
return list(self._definitions.values())
async def call(self, name: str, args: dict) -> dict:
"""首次调用时才触发加载。"""
if name not in self._definitions:
raise ValueError(f"未知工具: {name}")
if name not in self._impls:
# 此处才会 import 重型模块
self._impls[name] = self._loaders[name]()
impl = self._impls[name]
return await impl(args)
# ── 使用示例 ──────────────────────────────────────────────
registry = LazyToolRegistry()
# 注册时只存定义,不 import pandas
registry.register_lazy(
name="analyze_csv",
definition={
"name": "analyze_csv",
"description": "分析 CSV 文件并返回统计摘要",
"inputSchema": {
"type": "object",
"properties": {
"path": {"type": "string"},
"column": {"type": "string"},
},
"required": ["path"],
},
},
loader=lambda: _load_csv_analyzer(), # 真正的 import 推迟到调用时
)
def _load_csv_analyzer():
"""只有调用 analyze_csv 时才会执行。"""
import pandas as pd # 重型依赖,延迟到此处
from statistics import mean
async def analyzer(args: dict) -> dict:
df = pd.read_csv(args["path"])
col = args.get("column", df.columns[0])
return {
"content": [
{
"type": "text",
"text": (
f"列 {col}: 均值={df[col].mean():.2f}, "
f"行数={len(df)}"
),
}
]
}
return analyzer
TypeScript 实现:
interface ToolDefinition {
name: string;
description: string;
inputSchema: object;
}
type ToolLoader = () => Promise<(args: Record<string, unknown>) => Promise<unknown>>;
class LazyToolRegistry {
private definitions = new Map<string, ToolDefinition>();
private loaders = new Map<string, ToolLoader>();
private impls = new Map<string, Function>();
registerLazy(name: string, def: ToolDefinition, loader: ToolLoader): void {
this.definitions.set(name, def);
this.loaders.set(name, loader);
}
listTools(): ToolDefinition[] {
return Array.from(this.definitions.values()); // 无需加载
}
async call(name: string, args: Record<string, unknown>): Promise<unknown> {
if (!this.definitions.has(name)) throw new Error(`未知工具: ${name}`);
if (!this.impls.has(name)) {
const loader = this.loaders.get(name)!;
const impl = await loader(); // 首次调用才加载
this.impls.set(name, impl);
}
return this.impls.get(name)!(args);
}
}
// 使用:动态 import 延迟到首次调用
const registry = new LazyToolRegistry();
registry.registerLazy(
"analyze_csv",
{
name: "analyze_csv",
description: "分析 CSV 文件",
inputSchema: {
type: "object",
properties: { path: { type: "string" } },
required: ["path"],
},
},
async () => {
const mod = await import("./tools/csv-analyzer"); // 延迟 import
return mod.default;
}
);
1.3 启动优化效果对比
| 优化措施 | 优化前 | 优化后 | 提升 |
|---|---|---|---|
| 无优化(全量加载) | 3200ms | —— | —— |
| 延迟加载重型依赖 | 3200ms | 180ms | ~18x |
| + 数据库懒初始化 | 180ms | 95ms | ~2x |
| + 工具按需注册 | 95ms | 60ms | ~1.6x |
二、HTTP Server 连接池与并发控制
2.1 连接池配置
HTTP Server 通常使用 ASGI/WSGI 框架(Python)或 Node.js HTTP Server(TypeScript)。连接池的核心参数:
| 参数 | 作用 | 推荐值(中型应用) |
|---|---|---|
| max_connections | 最大并发连接数 | 200-500 |
| max_keepalive_connections | 保活连接数上限 | 50-100 |
| keepalive_timeout | 保活超时 | 30-65s |
| connection_timeout | 建连超时 | 5s |
| request_timeout | 请求总超时 | 60-300s |
2.2 Python(Uvicorn / FastAPI)
from contextlib import asynccontextmanager
from fastapi import FastAPI
import uvicorn
@asynccontextmanager
async def lifespan(app: FastAPI):
"""应用生命周期管理:启动时初始化,关闭时清理。"""
# 启动:初始化连接池(但可以是空池,按需创建)
app.state.db_pool = None # 懒初始化
yield
# 关闭:清理资源
if app.state.db_pool:
await app.state.db_pool.close()
app = FastAPI(lifespan=lifespan)
# Uvicorn 启动配置
if __name__ == "__main__":
uvicorn.run(
app,
host="0.0.0.0",
port=8000,
# ── 并发控制 ──
workers=4, # 进程数(=CPU 核心数)
loop="uvloop", # 高性能事件循环
http="httptools", # 高性能 HTTP 解析
limit_concurrency=500, # 全局并发连接上限
limit_max_requests=10000, # 处理 1 万次请求后重启(防内存泄漏)
timeout_keep_alive=30,
timeout_graceful_shutdown=10,
)
2.3 TypeScript(Node.js HTTP Server)
import http from "http";
import { Worker, isMainThread } from "worker_threads";
const PORT = 8000;
const MAX_CONCURRENCY = 500;
if (isMainThread) {
// 主线程:利用 cluster 模式启动多个 Worker
const numWorkers = 4;
for (let i = 0; i < numWorkers; i++) {
new Worker(__filename);
}
} else {
const activeRequests = new Set<http.IncomingMessage>();
const server = http.createServer((req, res) => {
// 并发控制:超过上限时拒绝
if (activeRequests.size >= MAX_CONCURRENCY) {
res.writeHead(503, { "Content-Type": "application/json" });
res.end(JSON.stringify({
jsonrpc: "2.0",
error: { code: -32603, message: "Server 过载,请稍后重试" },
}));
return;
}
activeRequests.add(req);
res.on("finish", () => activeRequests.delete(req));
handleMcpRequest(req, res);
});
server.keepAliveTimeout = 30000; // 30s
server.headersTimeout = 35000; // 略大于 keepAliveTimeout
server.maxConnections = MAX_CONCURRENCY;
server.listen(PORT);
}
async function handleMcpRequest(
req: http.IncomingMessage,
res: http.ServerResponse
) {
// ... JSON-RPC 路由逻辑
}
三、工具调用的超时与熔断策略
3.1 多层超时设计
Client 端 Server 端
┌──────────────────┐ ┌──────────────────┐
│ 请求级超时 30s │ │ 工具执行超时 25s │
│ ┌──────────────┐ │ │ ┌──────────────┐ │
│ │ 连接超时 5s │ │ ──网络──▶ │ │ 子操作超时 │ │
│ └──────────────┘ │ │ │ 10s / 15s │ │
└──────────────────┘ │ └──────────────┘ │
└──────────────────┘
| 超时层 | 推荐值 | 作用 |
|---|---|---|
| Client 连接超时 | 5s | 防止 DNS / TCP 层挂起 |
| Client 请求总超时 | 30s | 最外层保护 |
| Server 工具执行超时 | 25s | 略小于 Client 超时 |
| Server 子操作超时 | 10-15s | 数据库查询、外部 API |
3.2 Server 端超时实现(Python)
import asyncio
from functools import wraps
def with_timeout(seconds: float):
"""工具执行超时装饰器。"""
def decorator(func):
@wraps(func)
async def wrapper(*args, **kwargs):
try:
return await asyncio.wait_for(
func(*args, **kwargs), timeout=seconds
)
except asyncio.TimeoutError:
return {
"isError": True,
"content": [
{
"type": "text",
"text": f"工具执行超时({seconds}s),请缩小查询范围后重试",
}
],
"_meta": {"timeoutSeconds": seconds},
}
return wrapper
return decorator
# 使用
@with_timeout(25)
async def search_large_dataset(args: dict) -> dict:
return {"content": [{"type": "text", "text": "结果..."}]}
3.3 熔断器模式
当某个工具连续失败时,应当暂时停止调用它(熔断),避免级联故障。
TypeScript 实现:
type CircuitState = "closed" | "open" | "half-open";
interface CircuitConfig {
failureThreshold: number; // 连续失败多少次熔断
recoveryTimeoutMs: number; // 熔断后多久尝试半开
halfOpenMaxCalls: number; // 半开状态最大试探调用数
}
class CircuitBreaker {
private state: CircuitState = "closed";
private failureCount = 0;
private lastFailureTime = 0;
private halfOpenCalls = 0;
constructor(private config: CircuitConfig) {}
async execute<T>(fn: () => Promise<T>): Promise<T> {
if (this.state === "open") {
if (Date.now() - this.lastFailureTime > this.config.recoveryTimeoutMs) {
this.state = "half-open";
this.halfOpenCalls = 0;
} else {
throw new Error("CircuitBreaker: 熔断中,请求被拒绝");
}
}
if (this.state === "half-open" && this.halfOpenCalls >= this.config.halfOpenMaxCalls) {
throw new Error("CircuitBreaker: 半开状态调用数已满");
}
this.halfOpenCalls++;
try {
const result = await fn();
this.onSuccess();
return result;
} catch (e) {
this.onFailure();
throw e;
}
}
private onSuccess() {
this.failureCount = 0;
if (this.state === "half-open") {
this.state = "closed"; // 恢复
}
}
private onFailure() {
this.failureCount++;
this.lastFailureTime = Date.now();
if (this.state === "half-open") {
this.state = "open"; // 半开时失败,重新熔断
} else if (this.failureCount >= this.config.failureThreshold) {
this.state = "open";
}
}
getState(): CircuitState {
return this.state;
}
}
// 使用:为每个工具创建独立的熔断器
const toolBreakers = new Map<string, CircuitBreaker>();
function getBreaker(toolName: string): CircuitBreaker {
if (!toolBreakers.has(toolName)) {
toolBreakers.set(
toolName,
new CircuitBreaker({
failureThreshold: 5,
recoveryTimeoutMs: 30_000,
halfOpenMaxCalls: 1,
})
);
}
return toolBreakers.get(toolName)!;
}
async function callWithBreaker(toolName: string, fn: () => Promise<unknown>) {
const breaker = getBreaker(toolName);
return breaker.execute(fn);
}
3.4 熔断策略速查
| 工具特性 | failureThreshold | recoveryTimeout | 说明 |
|---|---|---|---|
| 只读查询 | 10 | 10s | 相对宽容 |
| 写操作 | 5 | 30s | 较严格 |
| 外部 API | 3 | 60s | 依赖不可控,更严格 |
| 本地计算 | 不熔断 | —— | 纯 CPU 操作不会级联 |
四、capabilities 缓存减少 discover 开销
4.1 为什么要缓存
discover / tools/list 等操作在每次会话开始时都会执行。如果 Server 的工具列表不频繁变化,反复请求纯属浪费。
| 操作 | 典型耗时 | 建议缓存 |
|---|---|---|
initialize | 50-100ms | 按进程缓存 |
tools/list | 20-80ms | 按 session 缓存 |
resources/list | 10-50ms | TTL 缓存 |
prompts/list | 10-30ms | TTL 缓存 |
4.2 Client 端缓存实现(Python)
import time
from typing import Any
class CapabilitiesCache:
"""capabilities 缓存,支持 TTL 与手动失效。"""
def __init__(self, default_ttl: int = 300):
self._cache: dict[str, tuple[float, Any]] = {}
self._default_ttl = default_ttl
def get(self, key: str) -> Any | None:
entry = self._cache.get(key)
if not entry:
return None
ts, val = entry
if time.time() - ts > self._default_ttl:
del self._cache[key]
return None
return val
def set(self, key: str, value: Any, ttl: int | None = None):
self._cache[key] = (time.time(), value)
def invalidate(self, key: str | None = None):
if key:
self._cache.pop(key, None)
else:
self._cache.clear()
class CachedMcpClient:
"""带缓存能力的 MCP Client。"""
def __init__(self, transport):
self._transport = transport
self._cache = CapabilitiesCache(default_ttl=300)
self._server_version: str | None = None
async def discover(self) -> dict:
"""带缓存的 discover。"""
cached = self._cache.get("discover")
if cached:
return cached
result = await self._transport.request("discover", {})
self._cache.set("discover", result)
self._server_version = result.get("serverInfo", {}).get("version")
return result
async def list_tools(self, force_refresh: bool = False) -> list[dict]:
"""带缓存的 tools/list。"""
if force_refresh:
self._cache.invalidate("tools")
cached = self._cache.get("tools")
if cached:
return cached
result = await self._transport.request("tools/list", {})
tools = result.get("tools", [])
self._cache.set("tools", tools)
return tools
async def call_tool(self, name: str, args: dict) -> dict:
"""调用工具——如果收到 -32601 Method not found 则自动失效缓存。"""
try:
return await self._transport.request(
"tools/call", {"name": name, "arguments": args}
)
except Exception as e:
if getattr(e, "code", None) == -32601:
# 工具不存在,可能是缓存过期
self._cache.invalidate("tools")
raise
4.3 缓存失效时机
| 事件 | 失效的缓存 |
|---|---|
| Server 重启(version 变化) | 全部 |
收到 -32601 Method not found | tools |
收到 -32023 InvalidResourceURI | resources |
| 定时 TTL 过期 | 对应 key |
手动调用 force_refresh=True | 指定 key |
五、SSE 连接的保活与重连
5.1 SSE 断连的原因
Streamable HTTP 传输中,Server 通过 SSE 向 Client 推送消息。SSE 连接(长连接)在以下情况会断开:
| 原因 | 频率 | 处理策略 |
|---|---|---|
| 网络抖动 | 偶发 | 自动重连 |
| 代理超时(如 Nginx proxy_read_timeout) | 周期性 | 保活心跳 |
| Server 重启/部署 | 偶发 | 指数退避重连 |
| 负载均衡器空闲回收 | 周期性 | 心跳保活 |
| 客户端网络切换 | 偶发 | 自动重连 |
5.2 保活心跳
# Server 端:定期发送 SSE 注释行作为心跳
import asyncio
from starlette.responses import StreamingResponse
async def sse_stream(request):
"""带心跳的 SSE 流。"""
queue: asyncio.Queue = asyncio.Queue()
async def heartbeat():
"""每 15 秒发送一个注释行,保持连接活跃。"""
while True:
await asyncio.sleep(15)
await queue.put(": heartbeat\n\n") # SSE 注释,Client 忽略
async def message_pump():
"""正常的消息推送。"""
async for msg in message_source():
await queue.put(f"data: {msg}\n\n")
asyncio.create_task(heartbeat())
asyncio.create_task(message_pump())
async def generate():
while True:
yield await queue.get()
return StreamingResponse(generate(), media_type="text/event-stream")
// Client 端:EventSource 自动重连 + 自定义超时检测
class ResilientSSEClient {
private eventSource: EventSource | null = null;
private lastMessageTime = Date.now();
private reconnectDelay = 1000;
private readonly maxDelay = 30_000;
constructor(private url: string, private sessionId: string) {
this.connect();
}
private connect() {
this.eventSource = new EventSource(
`${this.url}?sessionId=${this.sessionId}`,
{ withCredentials: true }
);
this.eventSource.onmessage = (event) => {
this.lastMessageTime = Date.now();
if (event.data.startsWith(":")) return; // 忽略心跳注释
const msg = JSON.parse(event.data);
this.handleMessage(msg);
};
this.eventSource.onerror = () => {
this.eventSource?.close();
this.scheduleReconnect();
};
}
private scheduleReconnect() {
// 指数退避
console.log(`SSE 断连,${this.reconnectDelay}ms 后重连...`);
setTimeout(() => {
this.reconnectDelay = Math.min(this.reconnectDelay * 2, this.maxDelay);
this.connect();
}, this.reconnectDelay);
}
private handleMessage(msg: any) {
// 成功收到业务消息后重置退避
this.reconnectDelay = 1000;
console.log("收到消息:", msg);
}
// 独立的死连接检测:即使没有 onerror,也能发现静默断连
startDeadConnectionWatcher() {
setInterval(() => {
if (Date.now() - this.lastMessageTime > 45_000) {
console.warn("SSE 疑似死连接,主动重连");
this.eventSource?.close();
this.scheduleReconnect();
}
}, 15_000);
}
}
5.3 重连参数建议
| 参数 | 推荐值 | 说明 |
|---|---|---|
| 初始退避 | 1s | 第一次重连的等待 |
| 最大退避 | 30s | 退避上限 |
| 退避系数 | 2x | 每次失败翻倍 |
| 心跳间隔 | 15s | Server 端发送频率 |
| 死连接超时 | 45s | 3 倍心跳间隔无消息则判定为死连接 |
六、监控指标体系
6.1 核心指标分层
┌─────────────────────────────────────────────────────┐
│ 业务指标层 │
│ 工具调用成功率 · 任务完成率 · 用户满意度 │
├─────────────────────────────────────────────────────┤
│ 服务指标层 │
│ P50/P99 延迟 · 错误率 · QPS · 并发连接数 │
├─────────────────────────────────────────────────────┤
│ 基础设施层 │
│ CPU · 内存 · 磁盘 IO · 网络带宽 · 进程存活 │
└─────────────────────────────────────────────────────┘
6.2 关键指标定义
| 指标 | 定义 | 告警阈值 |
|---|---|---|
| P99 延迟 | 99% 的请求在多少 ms 内完成 | > 5000ms |
| 错误率 | 错误请求数 / 总请求数 | > 5% |
| 工具调用频率 | 每个工具每分钟的调用次数 | 突增 3x 或归零 |
| 熔断次数 | 每小时触发熔断的次数 | > 10 |
| SSE 重连次数 | 每小时重连次数 | > 20 |
| discover 耗时 | discover 的平均/P99 耗时 | > 500ms |
| 进程启动时间 | STDIO Server 从 fork 到 ready | > 2000ms |
6.3 指标采集实现(Python)
import time
from collections import defaultdict
from dataclasses import dataclass, field
@dataclass
class MetricsCollector:
"""轻量级指标采集器,生产环境可对接 Prometheus。"""
_request_latencies: list[float] = field(default_factory=list)
_error_count: int = 0
_total_requests: int = 0
_tool_call_counts: dict[str, int] = field(
default_factory=lambda: defaultdict(int)
)
_circuit_open_count: int = 0
def record_request(self, tool: str, duration_ms: float, success: bool):
self._request_latencies.append(duration_ms)
self._total_requests += 1
self._tool_call_counts[tool] += 1
if not success:
self._error_count += 1
def record_circuit_open(self):
self._circuit_open_count += 1
def percentile(self, data: list[float], p: float) -> float:
"""计算百分位数。"""
if not data:
return 0
sorted_data = sorted(data)
idx = int(len(sorted_data) * p / 100)
return sorted_data[min(idx, len(sorted_data) - 1)]
def snapshot(self) -> dict:
"""生成指标快照,用于暴露给监控系统。"""
return {
"total_requests": self._total_requests,
"error_rate": (
self._error_count / self._total_requests
if self._total_requests > 0
else 0
),
"p50_latency_ms": self.percentile(self._request_latencies, 50),
"p99_latency_ms": self.percentile(self._request_latencies, 99),
"tool_calls": dict(self._tool_call_counts),
"circuit_opens": self._circuit_open_count,
}
# 全局采集器
metrics = MetricsCollector()
# 中间件:自动采集每个请求的指标
async def metrics_middleware(handler):
async def wrapper(request):
tool = request.get("params", {}).get("name", "unknown")
t0 = time.time()
success = True
try:
return await handler(request)
except Exception:
success = False
raise
finally:
metrics.record_request(
tool=tool,
duration_ms=round((time.time() - t0) * 1000, 2),
success=success,
)
return wrapper
6.4 Prometheus 格式导出
# 将指标导出为 Prometheus 文本格式
def export_prometheus(metrics: MetricsCollector) -> str:
snap = metrics.snapshot()
lines = [
"# HELP mcp_total_requests Total number of MCP requests",
"# TYPE mcp_total_requests counter",
f"mcp_total_requests {snap['total_requests']}",
"",
"# HELP mcp_error_rate Current error rate",
"# TYPE mcp_error_rate gauge",
f"mcp_error_rate {snap['error_rate']:.4f}",
"",
"# HELP mcp_p99_latency_ms P99 latency in milliseconds",
"# TYPE mcp_p99_latency_ms gauge",
f"mcp_p99_latency_ms {snap['p99_latency_ms']}",
"",
"# HELP mcp_tool_calls_total Tool call counts",
"# TYPE mcp_tool_calls_total counter",
]
for tool, count in snap["tool_calls"].items():
lines.append(f'mcp_tool_calls_total{{tool="{tool}"}} {count}')
return "\n".join(lines)
6.5 告警规则示例
# Prometheus AlertManager 规则
groups:
- name: mcp_alerts
rules:
- alert: McpHighErrorRate
expr: mcp_error_rate > 0.05
for: 5m
labels:
severity: critical
annotations:
summary: "MCP 错误率超过 5%"
description: "当前错误率 {{ $value }}"
- alert: McpP99LatencyHigh
expr: mcp_p99_latency_ms > 5000
for: 10m
labels:
severity: warning
annotations:
summary: "MCP P99 延迟超过 5 秒"
- alert: McpCircuitOpen
expr: increase(mcp_circuit_opens_total[1h]) > 10
labels:
severity: warning
annotations:
summary: "MCP 熔断器频繁开启"
七、生产部署检查清单
部署 MCP Server 到生产环境前,逐项确认:
| 类别 | 检查项 | 状态 |
|---|---|---|
| 启动 | 冷启动时间 < 2s | ☐ |
| 启动 | 延迟加载重型依赖 | ☐ |
| 连接 | 连接池上限已设置 | ☐ |
| 连接 | 并发限制已配置 | ☐ |
| 超时 | 工具执行有超时保护 | ☐ |
| 超时 | 熔断器已启用 | ☐ |
| 缓存 | capabilities 缓存已启用 | ☐ |
| 缓存 | 缓存失效策略已定义 | ☐ |
| SSE | 心跳保活已配置 | ☐ |
| SSE | 客户端重连有指数退避 | ☐ |
| 监控 | P99 延迟 / 错误率已采集 | ☐ |
| 监控 | 告警规则已配置 | ☐ |
| 安全 | stderr 未泄漏敏感信息 | ☐ |
| 安全 | 授权扩展已启用 | ☐ |
本篇小结
| 优化维度 | 关键手段 | 效果 |
|---|---|---|
| STDIO 启动 | 延迟加载工具 + 懒初始化 | 冷启动从秒级降到毫秒级 |
| HTTP 并发 | 连接池 + 并发限制 + Worker | 高并发下稳定 |
| 调用稳定性 | 多层超时 + 熔断器 | 防止级联故障 |
| discover 开销 | capabilities 缓存 | 减少重复请求 |
| SSE 连接 | 心跳保活 + 指数退避重连 | 长连接不断 |
| 可观测性 | 三层指标 + 告警规则 | 问题早发现 |
下篇预告
第 36 篇:MCP 安全加固——从传输层到工具沙箱
生产环境的 MCP 系统面临 Prompt 注入、权限越权、数据泄露等安全挑战,本篇系统讲解防护策略。
如果本篇内容对你有帮助,欢迎点赞收藏!有任何疑问,欢迎在评论区交流。
转载自 CSDN-专业IT技术社区
原文链接:https://blog.csdn.net/m0_68987304/article/details/163882942



