首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >企业级 MCP 最佳实践总结与思考

企业级 MCP 最佳实践总结与思考

作者头像
Wangzy
发布2026-06-22 19:08:17
发布2026-06-22 19:08:17
120
举报

前记:最近在重构故障根因分析 Agent。涉及到很多的MCP Server Tool开发,搜索了一圈对企业级的MCP-Server最佳实践介绍的不多,我开始意识到一个现实问题:单个 Server 的实现并不复杂,但当能力域、权限边界、风险等级、版本演进叠加在一起时,事情会迅速变得复杂。

带着这些疑问,系统回顾了协议文档与相关实践资料,并结合当前工程场景做了一次深入梳理。这篇文章,是这次思考过程的阶段性沉淀。

01

企业参考架构:控制面/ 数据面分离

1、分层架构总览

企业级落地宜采用「MCP 控制面 + 数据面」的参考架构,将治理能力上收为控制面,工具执行下沉为数据面。

2、多编排平台共存的接入模式

私有云场景下通常同时存在Dify、LangGraph、AutoGen 等多个智能体编排平台,建议统一通过 MCP 网关收口,各平台保留各自编排优势,工具访问行为全部由网关管控。

02

MCP Server 设计最佳实践

1、单一职责原则

核心原则:企业不应把MCP Server 设计成「万能代理」,而应以「小而专、可组合、受控」的方式拆分能力域,从组织与架构上天然抑制权限膨胀与上下文爆炸。

推荐按「业务域+ 风险等级」双维度拆分:

  • 高危写操作(删除/转账/发布/执行)→ 单独 Server,默认关闭,需二次确认
  • 只读检索与总结→ 通用 Server,较宽松的访问策略
  • 业务域切分示例:工单域Server、知识库域 Server、代码域 Server、风控域 Server
  • 同域内再按风险级别区分只读/ 读写 / 高危操作

2、工具定义(Tools)规范

参数描述要极度清晰,LLM 完全依赖 description 和 inputSchema 来决定是否、如何调用工具。描述不清晰是模型幻觉和误调用的根源。

代码语言:javascript
复制
# ✅ 好的工具定义示例(Python FastMCP)
@mcp.tool()
async def get_order_status(order_id: str) -> str:
    """查询指定订单的当前状态。

    Args:
        order_id: 订单号,格式为 ORD-XXXXXXXX(8位数字),
                  例如 ORD-12345678。不支持批量查询。
    Returns:
        JSON 格式的订单状态信息,包含 status、created_at、amount。
    """

# ❌ 描述不清晰的反例
@mcp.tool()
async def get_order(id: str) -> str:  # 参数名含义不明
    """Get order."""  # 描述极度匮乏

输入校验(inputSchema)要在工具层完成

  • 用zod(TypeScript)或 Pydantic/类型注解(Python)在 schema 层拦截非法输入
  • 不要把校验逻辑全压到业务层,让LLM 在调用前就能看到约束
  • 对枚举类型用enum 约束,对数值用 min/max 约束,对字符串用 pattern 约束

outputSchema:结构化输出替代长文本

  • 将关键工具输出(风控评估、权限查询、配置变更计划)定义为结构化schema
  • 模型主要消费结构化字段(消耗token 少),人类或后续步骤通过 resourcelink 读取全文
  • Host 侧强制校验 outputSchema,不合规结果视为错误,触发回滚或降级

3、错误处理:优雅返回,不要抛异常

官方最佳实践:将错误作为正常文本内容返回给LLM,而非让工具执行异常退出。LLM 可以理解「无法获取数据」并决定下一步,但无法从异常栈中恢复。

代码语言:javascript
复制
# ✅ 正确:错误作为可理解的内容返回
async def make_api_request(url: str) -> dict | None:
try:
response = await client.get(url, timeout=30.0)
response.raise_for_status()
return response.json()
except Exception as e:
logging.error(f'API request failed: {e}', exc_info=True)  # 记录到 stderr
return None  # 返回 None,由调用方决定如何告知 LLM

# 调用侧
data = await make_api_request(url)
if not data:
return '无法获取数据,请检查订单号是否正确或稍后重试。'  # LLM 可理解的友好文本

4、工具清单规模治理:防止上下文爆炸

Tools/List 返回的每个工具都携带 description 与 JSON Schema。当工具数量庞大或 schema 过于冗长,Host 若整体暴露给模型,会消耗大量 Token 并降低推理质量。

策略一:按域拆分Server,靠组合性而非「大而全」

  • 以「业务域+ 风险等级」作为拆分维度
  • Host 仅在需要时连接与暴露相应域的 tools
  • 不同风险等级的工具隔离在不同Server,通过网关权限控制访问

策略二:用Resources/URI Templates 承载数据面

  • 把大量「数据获取」从Tools 迁移到 Resources(resources/read + URI 模板)
  • Tools 只保留「需要副作用/计算」的动作(创建工单、执行部署、提交审批)
  • 按ID 读取实体、按条件分页查询 → 做成资源模板,由 Host 按需 read

策略三:分页+ 延迟暴露

  • Tools/List 明确支持分页(nextCursor)+ 变更通知(listChanged)
  • Host 先只取「少量核心工具」,在用户意图明确后再拉取后续工具集
  • 通过「按租户/角色/场景动态生成 tools/list」实现精准工具暴露

策略四:谨慎使用「通用路由工具(Router Tool)」

反模式警告:把N 个工具压缩成 1 个「万能工具」用 action 字段分支,虽减少工具数量,但会导致动作枚举复杂、校验困难、模型更易幻觉出不存在的 action。仅在动作集合稳定且可严格校验时使用。

03

FastAPI + FastMCP 多 Server 方案:防止上下文爆炸

这是私有云企业级部署中最核心的工程挑战之一:当MCP 工具数量增长至数十乃至数百个,单一 Server 加载所有工具会导致模型上下文「爆炸」,推理质量急剧下降。FastMCP + FastAPI 提供了一套完整的多 Server 拆分与挂载方案来解决这个问题。

1、问题根源:单体Server 的上下文爆炸

核心问题:tools/list 返回的每个工具都携带 name、description 和完整 inputSchema。100 个工具 × 平均 500 Token/工具描述 = 首次加载消耗约 5 万 Token。这不仅浪费成本,还会稀释模型对真正有用工具的注意力,导致「上下文腐烂」现象。

2、FastMCP 多 Server 拆分与挂载架构

FastMCP 提供了原生的 mount 机制,支持将多个子 Server 挂载到一个父 Server(或 FastAPI 应用)上,同时通过前缀命名空间隔离各域工具。

方案A:子 Server 挂载到主 FastMCP

代码语言:javascript
复制
# 文件结构
# servers/
#   main.py          ← 主入口,负责挂载与路由
#   crm_server.py    ← CRM 域(客户/工单/联系人)
#   finance_server.py ← 财务域(账单/报表/预算)
#   hr_server.py     ← HR 域(人员/考勤/薪资)
#   code_server.py   ← 代码域(高危,默认关闭)

# crm_server.py
from fastmcp import FastMCP

crm = FastMCP('crm-server')

@crm.tool()
async def get_customer(customer_id: str) -> dict:
    """查询客户基本信息。customer_id: 客户唯一标识,格式 CUS-XXXXXX。"""
    ...

@crm.tool()
async def create_ticket(customer_id: str, subject: str, priority: str) -> dict:
    """创建客户工单。priority: low/medium/high/urgent。"""
    ...

# finance_server.py
from fastmcp import FastMCP

finance = FastMCP('finance-server')

@finance.tool()
async def get_invoice(invoice_id: str) -> dict:
    """查询发票详情。invoice_id: 发票号,格式 INV-XXXXXXXX。"""


# main.py — 主入口,按域挂载,前缀隔离命名空间
from fastmcp import FastMCP
from crm_server import crm
from finance_server import finance
from hr_server import hr

main_mcp = FastMCP('enterprise-main')

# 挂载子 Server,工具名自动加前缀: crm_get_customer, finance_get_invoice
main_mcp.mount('crm', crm)       # → tools: crm_get_customer, crm_create_ticket
main_mcp.mount('finance', finance) # → tools: finance_get_invoice, ...
main_mcp.mount('hr', hr)          # → tools: hr_get_employee, ...
# 高危 Server 默认不挂载,需显式授权后动态挂载
# main_mcp.mount('code', code_server)  # 危险操作,按需开放

if __name__ == '__main__':
    main_mcp.run(transport='streamable-http', host='0.0.0.0', port=8000)   

方案B:多 Server 挂载到 FastAPI 应用

代码语言:javascript
复制
# app.py — FastAPI 作为容器,各域 Server 独立路由
from fastapi import FastAPI, Depends
from fastmcp import FastMCP
from fastmcp.server.auth import BearerAuthProvider
from crm_server import crm
from finance_server import finance
from hr_server import hr

app = FastAPI(title='Enterprise MCP Gateway')

# 各域 Server 挂载到独立路径,配合网关 RBAC 精确控制
# CRM 域:所有角色可访问
app.mount('/mcp/crm',     crm.get_asgi_app())

# 财务域:仅 finance_role 可访问(由网关层 RBAC 控制)
app.mount('/mcp/finance', finance.get_asgi_app())

# HR 域:仅 hr_manager 可访问
app.mount('/mcp/hr',      hr.get_asgi_app())

# 健康检查 & 指标
@app.get('/health')
async def health(): return {'status': 'ok'}

# uvicorn app:app --host 0.0.0.0 --port 8000 --workers 4

3、动态工具发现:元工具模式(Meta-Tool Pattern)

对于工具数量达到50+ 的大规模场景,即使拆分了多个 Server,单个 Server 内的工具数量也可能偏多。此时应在 Server 内实现「渐进式公开(Progressive Disclosure)」模式。

代码语言:javascript
复制
# meta_server.py — 元工具模式:只暴露两个入口工具
from fastmcp import FastMCP
import json

meta = FastMCP('meta-discovery')

# 所有可用工具的分类索引(不含 schema 细节)
TOOL_CATALOG = {
    'crm': ['get_customer', 'create_ticket', 'update_contact', 'search_customers'],
    'finance': ['get_invoice', 'generate_report', 'check_budget'],
    'hr': ['get_employee', 'check_attendance', 'request_leave'],
}

@meta.tool()
async def list_available_capabilities(domain: str = '') -> str:
    """获取可用工具的分类索引。
    domain: 可选,限定查询域(crm/finance/hr),为空则返回所有域。
    返回工具名列表,不含 schema 细节(节省 Token)。
    """
    if domain:
        return json.dumps(TOOL_CATALOG.get(domain, {}), ensure_ascii=False)
    return json.dumps(TOOL_CATALOG, ensure_ascii=False)

@meta.tool()
async def request_tool_schema(tool_name: str) -> str:
    """按需加载指定工具的完整 schema 和使用说明。
    tool_name: 工具名,从 list_available_capabilities 返回的列表中选择。
    """
    # 从注册表按需返回完整 schema,而不是一次性加载全部
    return TOOL_REGISTRY.get_schema(tool_name)

在理论估算场景下,可将初始化 Token 成本从数十万级降低到千级规模,具有数量级优化效果。模型先调用 listavailablecapabilities 了解有哪些工具,再按需调用 requesttoolschema 获取具体参数,最后才真正调用目标工具。

4、语义检索工具发现(向量化方案)

当工具数量达到百级别时,元工具模式的分类索引本身也可能变大。更进一步的方案是将工具描述向量化,通过语义搜索动态检索最匹配的工具子集。

代码语言:javascript
复制
# semantic_discovery.py — 语义工具发现
from fastmcp import FastMCP
from qdrant_client import QdrantClient
from sentence_transformers import SentenceTransformer

discovery = FastMCP('semantic-discovery')
embedder = SentenceTransformer('BAAI/bge-m3')   # 中文友好的嵌入模型
qdrant = QdrantClient(url='http://qdrant:6333')  # 私有云向量数据库

@discovery.tool()
async def find_tools(query: str, top_k: int = 5) -> list[dict]:
    """根据自然语言描述语义搜索最相关的工具。
    query: 描述你需要完成的任务,例如「查询客户的历史订单」。
    top_k: 返回最相关的工具数量,默认 5 个。
    """
    query_vec = embedder.encode(query).tolist()
    results = qdrant.search(
        collection_name='mcp_tools',
        query_vector=query_vec,
        limit=top_k,
    )
    return [
        {'tool_name': r.payload['name'], 'description': r.payload['desc'],
         'server': r.payload['server'], 'score': r.score}
        for r in results
    ]

# 工具注册时自动建立向量索引(在 Server 启动时执行)
async def index_tools_to_qdrant(mcp_servers: list[FastMCP]):
    for server in mcp_servers:
        for tool in server.list_tools():
            vec = embedder.encode(f'{tool.name}: {tool.description}').tolist()
            qdrant.upsert('mcp_tools', points=[{
                'id': hash(tool.name), 'vector': vec,
                'payload': {'name': tool.name, 'desc': tool.description,
                            'server': server.name}
            }])

5、代码执行模式:终极上下文压缩

当工具需要处理大数据集(如100MB 日志文件)时,将数据全量读入上下文是不可接受的。代码执行模式让模型编写处理逻辑,在沙箱内直接执行,只将结果摘要返回给模型。

代码语言:javascript
复制
# code_execution_server.py — 沙箱代码执行(高危,需严格权限控制)
from fastmcp import FastMCP
import subprocess, tempfile, os, json

code_exec = FastMCP('sandboxed-code-executor')

@code_exec.tool()
async def execute_analysis_code(code: str, data_path: str) -> dict:
    """在沙箱内执行数据分析代码,返回结构化结果。
    code: Python 代码字符串,可直接操作 data_path 指向的文件。
    data_path: 允许访问的数据文件路径(必须在白名单目录内)。
    返回: {'stdout': ..., 'result': ..., 'error': null}
    注意: 执行环境无网络访问,无写权限,超时 30 秒自动终止。
    """
    # 路径白名单校验(防路径穿越)
    allowed_prefix = '/data/sandbox/'
    if not os.path.realpath(data_path).startswith(allowed_prefix):
        return {'error': 'Access denied: path outside sandbox'}

    with tempfile.NamedTemporaryFile(suffix='.py', mode='w', delete=False) as f:
        f.write(code)
        script = f.name
    try:
        # gVisor 沙箱执行(配合 K8s RuntimeClass 使用)
        result = subprocess.run(
            ['python3', script],
            capture_output=True, text=True, timeout=30,
            env={'PATH': '/usr/bin', 'DATA_PATH': data_path}  # 最小环境变量
        )
        return {'stdout': result.stdout[:5000], 'error': result.stderr or None}
    finally:
        os.unlink(script)

04

MCP-Server的调试

1、MCP Inspector(官方推荐)

这是 Anthropic 官方提供的调试工具,类似于 MCP 的 "Postman"。

写一段测试代码如下:

代码语言:javascript
复制
### test-mcp-server.js

#!/usr/bin/env node
/**
 * 测试用 MCP Server - 供 MCP Inspector 验证
 *
 * 参考: https://github.com/modelcontextprotocol/inspector
 *
 * 启动方式(二选一):
 *   1. npx @modelcontextprotocol/inspector node test-mcp-server.js
 *   2. npx @modelcontextprotocol/inspector --config inspector-config.json
 *
 * 启动后浏览器打开 http://localhost:6274 即可在 Inspector 中测试 Tools / Resources / Prompts。
 */
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
  CallToolRequestSchema,
  ListToolsRequestSchema,
  ListResourcesRequestSchema,
  ReadResourceRequestSchema,
  ListPromptsRequestSchema,
  GetPromptRequestSchema,
} from '@modelcontextprotocol/sdk/types.js';
const server = new Server(
  {
    name: 'test-mcp-server',
    version: '1.0.0',
  },
  {
    capabilities: {
      tools: {},
      resources: {},
      prompts: {},
    },
  }
);
// ---------- Tools ----------
server.setRequestHandler(ListToolsRequestSchema, async () => ({
  tools: [
    {
      name: 'echo',
      description: '回显输入的文本,用于验证工具调用',
      inputSchema: {
        type: 'object',
        properties: {
          message: { type: 'string', description: '要回显的文本' },
        },
        required: ['message'],
      },
    },
    {
      name: 'add',
      description: '两数相加',
      inputSchema: {
        type: 'object',
        properties: {
          a: { type: 'number', description: '第一个数' },
          b: { type: 'number', description: '第二个数' },
        },
        required: ['a', 'b'],
      },
    },
  ],
}));
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  const { name, arguments: args } = request.params;
  if (name === 'echo') {
    return {
      content: [{ type: 'text', text: `Echo: ${args?.message ?? '(empty)'}` }],
    };
  }
  if (name === 'add') {
    const a = Number(args?.a);
    const b = Number(args?.b);
    if (Number.isNaN(a) || Number.isNaN(b)) {
      return {
        content: [{ type: 'text', text: 'Error: a 和 b 必须是数字' }],
        isError: true,
      };
    }
    return {
      content: [{ type: 'text', text: `${a} + ${b} = ${a + b}` }],
    };
  }
  return {
    content: [{ type: 'text', text: `Unknown tool: ${name}` }],
    isError: true,
  };
});
// ---------- Resources ----------
const sampleResource = {
  title: 'Inspector 测试数据',
  items: ['item1', 'item2', 'item3'],
  timestamp: new Date().toISOString(),
};
server.setRequestHandler(ListResourcesRequestSchema, async () => ({
  resources: [
    {
      uri: 'test://sample',
      name: 'Sample Data',
      description: '供 Inspector 测试的示例资源',
      mimeType: 'application/json',
    },
  ],
}));
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
  const { uri } = request.params;
  if (uri === 'test://sample') {
    return {
      contents: [
        {
          uri,
          mimeType: 'application/json',
          text: JSON.stringify(sampleResource, null, 2),
        },
      ],
    };
  }
  throw new Error(`Unknown resource: ${uri}`);
});
// ---------- Prompts ----------
server.setRequestHandler(ListPromptsRequestSchema, async () => ({
  prompts: [
    {
      name: 'hello',
      description: '简单的问候提示,用于验证 Prompts',
      arguments: [
        { name: 'name', description: '对方的名字', required: true },
      ],
    },
  ],
}));
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
  const { name, arguments: args } = request.params;
  if (name === 'hello') {
    const userName = args?.name ?? 'World';
    return {
      description: '问候提示',
      messages: [
        {
          role: 'user',
          content: {
            type: 'text',
            text: `请用一句话友好地问候:${userName}`,
          },
        },
      ],
    };
  }
  throw new Error(`Unknown prompt: ${name}`);
});
// ---------- 启动 ----------
async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
  console.error('Test MCP Server 已启动,可在 Inspector 中验证');
}
main().catch((err) => {
  console.error('Server error:', err);
  process.exit(1);
});

安装官方inspector

安装后通过浏览器打开inspector页面,点击connect

connect后可以在页面上调试Resources、Prompts、Tools等

如下页面是调试上述代码中写好的add tools demo

2、Claude Desktop 本地接入测试

将 Server 配置到 Claude Desktop 的配置文件中,直接在对话中测试:

代码语言:javascript
复制
`` // ~/Library/Application Support/Claude/claude_desktop_config.json (macOS)
`` {
``   "mcpServers": {
``     "my-server": {
``       "command": "node",
``       "args": ["/path/to/your/server.js"]
``     }
``   }
`` }

重启 Claude Desktop 后,在对话中直接触发工具调用,观察是否正常响应。

3、命令行手动发送 JSON-RPC 消息

MCP 底层是 JSON-RPC 协议,可以直接通过 stdin/stdout 手动交互:

代码语言:javascript
复制
# 启动 server 后,发送初始化消息
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' | node your-server.js

适合快速验证协议层面是否正常。

4、编写测试客户端

用官方 SDK 写一个简单的测试脚本:

代码语言:javascript
复制
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";

const transport = new StdioClientTransport({
  command: "node",
  args: ["./your-server.js"],
});

const client = new Client({ name: "test-client", version: "1.0.0" }, {});
await client.connect(transport);

// 列出所有工具
const tools = await client.listTools();
console.log(tools);

// 调用具体工具
const result = await client.callTool({
  name: "your_tool_name",
  arguments: { param1: "value1" },
});
console.log(result);

05

治理、版本管理与变更流程

1、组织角色分工

2、三类策略模板

a、暴露面策略(白名单/黑名单)

  • 哪些Server/Tools/Resources/Prompts 允许在某租户/项目/环境启用
  • 默认最小集合,按需开通;Tools 规范要求 UI 清晰展示暴露给模型的工具并支持确认/拒绝

b、范围与最小化策略

  • 对Resources/read、Roots/list 等建立强边界(例如只读、限定目录、禁止写入/执行)
  • 官方安全最佳实践中「scope minimization」的核心落点

c、版本与回滚策略

  • 协议版本(protocolVersion)、扩展版本、Server 版本三条线并行管理
  • Lifecycle 初始化握手协商版本与能力,适合做灰度与回滚门禁
  • 扩展机制要求在capabilities 中协商并支持 graceful degradation

3、投产变更管理流程

1)需求提出:新增/修改 MCP Server 或 Tools

2)风险分级:数据敏感/ 执行权限 / 外部依赖

3)设计评审:范围最小化、资源边界、回滚方案

4)实现与测试:Inspector 调试 + Conformance 一致性测试(作为 CI 门禁必备步骤)

5)安全评审:授权/密钥/注入防护/审计点

6)灰度发布:按租户/项目/环境启用白名单

7)上线监控:调用量、错误率、延迟、Token 成本、异常模式

8)归档证据:变更记录+ 审计日志 + 评测报告(合规要求)

4、SDK 选型原则

官方SDK 分四个 Tier,建议优先 Tier 1 + 与既有栈/运维体系匹配:

无论选哪种SDK,都应将 MCP Inspector(交互式调试)与 Conformance(协议一致性测试)纳入 CI 门禁,用一致性测试抵抗「实现偏差导致的安全/兼容事故」。

06

可观测性与运维

1、三层可观测体系

2、审计要求(每次调用必须记录)

  • 谁(用户身份/ Agent 身份)调用了什么(工具名 + 参数摘要)
  • 何时调用(时间戳,精确到毫秒)
  • 访问了哪类数据(资源URI / 数据分级标签)
  • 是否经过人工确认(Human-in-the-Loop 确认记录)
  • 调用结果(成功/失败/被拒绝)

合规要求:对每一个tools/call、resources/read、sampling/createMessage 都需建立完整的可追溯证据链,支持审计复查与合规举证。

3、工具循环成本控制

  • 设置最大循环轮数上限(例如10 轮),超限自动终止
  • 最后一轮强制toolChoice=none,避免无限循环
  • 按会话/用户/团队设置 Token 预算与告警阈值
  • 对「同一会话短时间高频读取敏感资源」设置异常告警,作为安全事件处理

4、一致性检测:用outputSchema 约束可重复性

  • 把关键工具输出定义为结构化schema(JSON Schema 2020-12 格式)
  • Host 侧强制校验,不合规结果触发回滚或降级
  • Server 返回结构化内容时,兼容性考虑同时提供序列化文本版本

07

结语

企业级 MCP 的真正难点,并不在于“能不能把工具接起来”,而在于如何在复杂组织环境中建立一套可控、可治理、可审计、可演进的能力体系。

当工具数量从几个增长到几十、上百个,当不同业务域与风险等级交织在一起,问题的本质就不再是代码实现,而是架构边界、权限收敛、上下文控制以及生命周期治理。

本文更多是阶段性的系统梳理,部分设计仍在工程实践中持续验证。后续若有新的实战经验与踩坑总结,也会继续沉淀分享。

希望这篇内容,能为正在探索企业级 MCP 落地的团队提供一些结构化参考。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-03-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 周银杂谈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前记:最近在重构故障根因分析 Agent。涉及到很多的MCP Server Tool开发,搜索了一圈对企业级的MCP-Server最佳实践介绍的不多,我开始意识到一个现实问题:单个 Server 的实现并不复杂,但当能力域、权限边界、风险等级、版本演进叠加在一起时,事情会迅速变得复杂。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档