news 2026/9/14 11:06:59

DeepCode MCP Server 构建最佳实践:从命名规范、响应设计到安全加固的完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
DeepCode MCP Server 构建最佳实践:从命名规范、响应设计到安全加固的完整指南

DeepCode MCP Server 构建最佳实践:从命名规范、响应设计到安全加固的完整指南

【免费下载链接】DeepCode"DeepCode: Open Agentic Coding (Agent Harness & Loop Engineering & Multi-Agent Orchestration)"项目地址: https://gitcode.com/GitHub_Trending/deepc/DeepCode

导读

本文是 DeepCode 开源仓库内置mcp-builder技能中通用 MCP(Model Context Protocol)服务端构建指南的完整解读。它面向两类读者:一是要为自己的服务(Slack、GitHub、Jira 等)编写高质量 MCP 服务器、让 LLM 能顺畅调用外部 API 的开发者;二是要在 DeepCode 这一 Agentic Coding 平台中注册、配置与消费 MCP 服务器的使用者。读完本文,你将掌握一套可直接落地的 MCP 服务器设计规范——包括服务器/工具命名、JSON 与 Markdown 双响应格式、分页元数据、stdio 与 Streamable HTTP 传输选型、OAuth 2.1 与 API Key 安全实践、工具注解语义以及完整的测试与文档要求,并能从 DeepCode 的运行时实现(core/mcp)中看到这些规范在真实产品中的落地形态。

一、文档定位:mcp-builder 技能体系中的"通用准则"

在 DeepCode 仓库中,mcp-builder是一个内置技能,其总纲文件 SKILL.md 将创建 MCP 服务器的流程划分为四个阶段:深度调研与规划(Phase 1)、实现(Phase 2)、评审与测试(Phase 3)、创建评估(Phase 4)。其中阶段 1.3 明确要求加载本文档——mcp_best_practices.md,并称之为"Core guidelines / Universal MCP guidelines"。

该文档在整个技能体系中处于"语言无关的通用规范"层,与另外三份文档构成完整体系:

文档(仓库根目录相对路径)作用
reference/mcp_best_practices.md通用最佳实践:命名、响应、分页、传输、安全、注解、错误处理、测试、文档(本文主题)
reference/python_mcp_server.mdPython/FastMCP 专属实现指南(Pydantic 校验、@mcp.tool注册、完整示例)
reference/node_mcp_server.mdNode/TypeScript 专属实现指南(Zod 校验、registerTool注册、完整示例)
reference/evaluation.mdMCP 服务器评估体系:如何用 10 道可验证问题检验 LLM 对服务器的使用效果

DeepCode 项目自述为 "Open Agentic Coding (Agent Harness & Loop Engineering & Multi-Agent Orchestration)",其自身的 MCP 运行时(core/mcp/runtime.py)实现了对这些规范的消费端支持——包括服务器启动生命周期、工具发现与注册、注解解析、审批模式等,后文将逐一对应展开。

二、命名规范:让模型一眼找到正确的工具

2.1 服务器命名(Server Naming)

最佳实践文档给出了与语言绑定、且易于从任务描述推断的命名模式:

  • Python{service}_mcp(小写 + 下划线),例如slack_mcpgithub_mcpjira_mcp
  • Node/TypeScript{service}-mcp-server(小写 + 连字符),例如slack-mcp-servergithub-mcp-serverjira-mcp-server

命名应满足四条约束:通用(不绑定具体功能特性)、能描述所集成的服务易于从任务描述中推断不含版本号或日期

这一约定在语言专属指南中被进一步落实为可运行的代码:Python 侧初始化mcp = FastMCP("example_mcp")(见 python_mcp_server.md),TypeScript 侧初始化new McpServer({ name: "example-mcp", version: "1.0.0" })(见 node_mcp_server.md)。

在 DeepCode 消费端,服务器名被严格校验:core/mcp/models.py 中的validate_server_name()使用正则^[A-Za-z0-9][A-Za-z0-9._-]{0,79}$,即 1~80 个字符、仅允许字母数字与.-_,否则抛出McpConfigurationError。这意味着服务端命名的"易推断"与消费端的"可解析"是相互配套的。

2.2 工具命名(Tool Naming)

工具命名规范可以浓缩为四条:

  1. 使用 snake_case:如search_userscreate_projectget_channel_info
  2. 携带服务前缀:要预见到你的 MCP 服务器会与其他 MCP 服务器并存,用slack_send_message而非send_message,用github_create_issue而非create_issue
  3. 动作导向:以动词开头(get、list、search、create 等);
  4. 足够具体:避免与其他服务器冲突的通用名。

格式归纳为:{service}_{action}_{resource},例如slack_send_messagegithub_create_issue

这条规范在 DeepCode 的运行时中得到了"双重保障"式的实现。见 core/mcp/naming.py 的visible_tool_name()

  • 每个来自 MCP 服务器的工具,会被映射为mcp__{server}__{tool}形式(如mcp__slack__send_message),天然携带服务前缀;
  • 名称长度上限 64 字符(MAX_TOOL_NAME_LENGTH = 64),超出时用 SHA-256 摘要(前 10 位十六进制)做确定性后缀,既保证唯一又可复现;
  • 遇到重名时自动追加_1_2编号,不会覆盖其他已注册工具。

也就是说,即使服务器作者漏写了服务前缀,DeepCode 也会在模型可见层强制带上mcp__<server>__前缀以避免跨服务器冲突(原始工具名仍以McpToolIdentity.raw_name保留,见 core/mcp/tools.py)。这在 tests/test_mcp_runtime.py 等测试中有覆盖。

三、工具设计:描述要"窄而准"

工具设计(Tool Design)部分强调:

  • 工具描述必须窄范围、无歧义地描述其功能;
  • 描述必须与实际功能精确匹配(防幻觉);
  • 提供工具注解(readOnlyHintdestructiveHintidempotentHintopenWorldHint);
  • 保持操作聚焦且原子,一个工具只做一件事。

Python 实现指南进一步给出操作要点:描述应由函数签名 + docstring 自动生成(FastMCP 特性),docstring 中应包含参数说明、返回 JSON schema、使用示例("Use when / Don't use when")、错误处理说明。TypeScript 侧则强调:description字段必须显式提供,JSDoc 注释不会自动提取;inputSchema必须是 Zod schema 对象(而非 JSON schema);outputSchema应尽量定义以输出结构化数据。

四、响应格式:JSON 与 Markdown 双轨并行

最佳实践文档规定:所有返回数据的工具都应支持多种格式,通过response_format参数切换。

JSON 格式(response_format="json"——面向程序化处理:

  • 机器可读的结构化数据;
  • 包含所有可用字段与元数据;
  • 字段名与类型保持一致。

Markdown 格式(response_format="markdown",通常为默认)——面向人类/LLM 阅读:

  • 使用标题、列表与排版增强可读性;
  • 将时间戳转换为人类可读格式(如2024-01-15 10:30:00 UTC而非 epoch);
  • 显示名 + ID 并列展示(如@john.doe (U123456));
  • 省略冗余元数据(如只保留一个头像 URL,而非全部尺寸);
  • 按逻辑对相关信息分组。

Python 侧推荐用StrEnum定义ResponseFormat,例如:

from enum import Enum class ResponseFormat(str, Enum): MARKDOWN = "markdown" JSON = "json" class UserSearchInput(BaseModel): query: str = Field(..., description="Search query") response_format: ResponseFormat = Field( default=ResponseFormat.MARKDOWN, description="Output format: 'markdown' for human-readable or 'json' for machine-readable" )

TypeScript 侧用z.nativeEnum(ResponseFormat).default(ResponseFormat.MARKDOWN)实现等价约束,并在返回时同时给出content(文本展示)与structuredContent(结构化数据)——后者是 TypeScript SDK 支持"文本 + 结构化"双通道的现代模式。

DeepCode 消费端的处理与此呼应:core/mcp/tools.py 的_result_text()会遍历结果的content块提取文本,并在没有文本块时回退读取structuredContent并序列化为 JSON——说明服务端返回的两种形态在 DeepCode 中都能被正确呈现给模型。

五、分页规范:永远尊重 limit 参数

对于列出资源的工具,最佳实践文档要求:

  • 始终尊重limit参数
  • 实现分页:使用offset或游标(cursor)分页;
  • 返回分页元数据:has_morenext_offset/next_cursortotal_count
  • 绝不把全部结果一次性加载进内存(尤其针对大数据集);
  • 默认限制合理:通常 20~50 条。

文档给出的示例分页响应:

{ "total": 150, "count": 20, "offset": 0, "items": [...], "has_more": true, "next_offset": 20 }

在 Python 实现指南中,对应的字段约束是limitge=1, le=100,默认 20)与offsetge=0,默认 0),且has_more通过total > offset + len(items)计算。TypeScript 指南还额外引入CHARACTER_LIMIT常量(示例为 25000 字符)防止响应过大撑爆上下文,超限时截断并在消息中提示Use 'offset' parameter or add filters to see more results.

这与 DeepCode 的上下文管理哲学一致:Agent 的上下文窗口是稀缺资源,工具应返回"聚焦、相关"的数据(SKILL.md 阶段 1.1 的 Context Management 要求),分页 + 过滤正是实现手段。

六、传输层选型:stdio 还是 Streamable HTTP

6.1 两种传输的特性

Streamable HTTP——适合远程服务器、Web 服务、多客户端场景:

  • 基于 HTTP 的双向通信;
  • 支持多个并发客户端;
  • 可作为 Web 服务部署;
  • 支持服务器到客户端的通知(server-to-client notifications)。

stdio——适合本地集成、命令行工具:

  • 标准输入/输出流通信;
  • 设置简单,无需网络配置;
  • 作为客户端的子进程运行;
  • 重要:stdio 服务器不应向 stdout 打日志(日志请走 stderr)。

文档还明确指出:避免使用 SSE(已弃用,被 Streamable HTTP 取代)。

6.2 选型对照表

评判维度stdioStreamable HTTP
部署方式本地(Local)远程(Remote)
客户端单个(Single)多个(Multiple)
复杂度低(Low)中等(Medium)
实时性无(No)有(Yes)

6.3 DeepCode 中的传输契约与真实示例

DeepCode 的服务器定义模型(core/mcp/models.py 的McpServerDefinition)将传输类型限定为type: Literal["stdio", "sse", "streamableHttp"],并通过_transport_contract模型校验器强制执行互斥契约

  • stdio服务器必须command,且不得定义任何 HTTP 字段(urlheadersbearerTokenEnvVar等);
  • HTTP 类服务器(sse/streamableHttp)必须有合法的http/httpsURL,且不得定义 stdio 进程字段(commandargscwdenv等);
  • required(必需)服务器不能deferLoading(延迟加载);
  • 传输类型不会从 URL 后缀或命令存在与否推断,必须显式声明。

内置预设文件 core/mcp/presets.json 给出了真实世界的选型样例:

{ "id": "browserbase", "server": { "type": "streamableHttp", "url": "https://mcp.browserbase.com/mcp", "envUrlParams": {"browserbaseApiKey": "BROWSERBASE_API_KEY"}, "toolTimeoutSeconds": 60, "approvalMode": "writes" } }, { "id": "playwright", "server": { "type": "stdio", "command": "npx", "args": ["-y", "@playwright/mcp@latest"], "toolTimeoutSeconds": 60, "approvalMode": "writes" } }

可以看到:云端托管的 Browserbase 用streamableHttp远程接入,本地的 Playwright 用stdio拉起子进程——与最佳实践文档的选型标准完全一致。

七、安全最佳实践:认证、校验与防护

7.1 认证与授权

OAuth 2.1

  • 使用来自权威机构签发的证书进行安全的 OAuth 2.1;
  • 处理请求前先校验访问令牌
  • 只接受明确面向你服务器签发的令牌。

API Keys

  • API Key 存于环境变量,绝不写死在代码里;
  • 服务器启动时即校验 Key 的有效性;
  • 认证失败时给出清晰的错误消息。

DeepCode 对此提供了更强的"存储边界"约束:core/mcp/models.py 的validate_no_literal_secrets()会检测envheaders中任何看起来敏感的名称(匹配authorizationcookieapi_keypasswordsecretprivate_key等模式),一旦发现即抛出McpConfigurationError,强制改用envVars(转发环境变量)、credentialEnv(引用用户连接的凭据,格式provider:<connection-id>)或bearerTokenCredential。同时 core/mcp/runtime.py 的McpSessionRuntime注释强调:凭据只在连接启动前一刻解析,绝不进入清单、诊断信息或序列化后的运行时计划。

7.2 输入校验

  • 对文件路径做清洗,防止目录遍历(directory traversal);
  • 校验 URL 与外部标识符;
  • 检查参数大小与取值范围;
  • 在系统调用中防止命令注入;
  • 对所有输入使用schema 校验(Pydantic / Zod)

Python 侧推荐 Pydantic v2 写法:model_config = ConfigDict(str_strip_whitespace=True, validate_assignment=True, extra='forbid')+Field(..., min_length=1, max_length=100)约束 +@field_validator自定义校验。TypeScript 侧用 Zod:.min(2, "Query must be at least 2 characters").int().max(100),并用.strict()禁止多余字段。DeepCode 的McpServerDefinition对 header 名、环境变量名、URL 参数名也都有正则校验,防止注入类攻击。

7.3 错误处理

  • 不向客户端暴露内部错误;
  • 安全相关的错误在服务端记录日志
  • 提供有用但不泄露细节的错误消息;
  • 出错后正确清理资源。

7.4 DNS Rebinding 防护(本地 Streamable HTTP)

对于本地运行的 Streamable HTTP 服务器:

  • 启用 DNS rebinding 防护;
  • 校验所有入站连接的Origin头;
  • 绑定127.0.0.1而非0.0.0.0

八、工具注解(Tool Annotations):hint 而非安全保证

最佳实践文档给出了四个注解的语义表:

注解类型默认值含义
readOnlyHintbooleanfalse工具不修改其环境
destructiveHintbooleantrue工具可能执行破坏性更新
idempotentHintbooleanfalse相同参数重复调用无额外效果
openWorldHintbooleantrue工具与外部实体交互

文档特别强调:注解是提示(hints),不是安全保证(guarantees)。客户端不应仅凭注解做安全关键决策。

这一原则在 DeepCode 中得到了教科书式的落实。见 core/mcp/tools.py 的McpToolAdapter.read_only属性:

@property def read_only(self) -> bool: # MCP annotations are hints, not grants. Unknown is deliberately # mutating so default/writes policies fail toward confirmation. return self.annotations.read_only

代码注释直译即为"注解是提示,不是授权"。当注解缺失时,DeepCode 故意按"可写"(mutating)处理,让默认/写策略向需要确认的方向失败(fail toward confirmation),即宁可让写操作触发人工审批,也不因缺失注解而放行。注解通过 core/mcp/models.py 的McpToolAnnotations.from_sdk()从 SDK 定义解析,并会以approvalMode(auto/prompt/writes/approve)叠加到全局权限之上,形成 MCP 专属的审批层级。

九、错误处理与错误消息设计

最佳实践文档要求:

  • 使用标准 JSON-RPC 错误码
  • 工具错误在 result 对象内上报(而非协议层错误);
  • 提供有帮助、具体、带下一步建议的错误消息;
  • 不暴露内部实现细节;
  • 出错时妥善清理资源。

文档给出的 TypeScript 错误处理示例(工具内部捕获并返回isError):

try { const result = performOperation(); return { content: [{ type: "text", text: result }] }; } catch (error) { return { isError: true, content: [{ type: "text", text: `Error: ${error.message}. Try using filter='active_only' to reduce results.` }] }; }

注意两个细节:一是错误通过isError: true放在结果对象中返回,而不是中断 JSON-RPC 协议;二是错误消息末尾附上了可执行的下一步建议Try using filter='active_only'...)——这正是"Actionable Error Messages"原则的体现(SKILL.md 阶段 1.1)。

Python 指南进一步示范了按 HTTP 状态码分类的错误映射:404→"请检查 ID 是否正确"、403→"权限不足"、429→"触发限流,请稍后重试"、超时→"请重试"。DeepCode 消费端在 core/mcp/tools.py 的execute()中会读取result.isError并完整透传文本、附带approvalMode等元数据,同时通过log_mcp_call记录调用遥测(观测失败不影响工具结果)。

十、测试要求:五类测试全覆盖

最佳实践文档要求全面的测试覆盖:

  • 功能测试(Functional):验证有效/无效输入下的正确执行;
  • 集成测试(Integration):测试与外部系统的交互;
  • 安全测试(Security):校验认证、输入清洗、限流;
  • 性能测试(Performance):检查负载与超时下的行为;
  • 错误处理(Error Handling):确保错误上报与资源清理正确。

语言专属指南给出的构建与冒烟方法:

# TypeScript:先构建再测试,用 MCP Inspector 交互调试 npm run build npx @modelcontextprotocol/inspector # Python:语法校验 + MCP Inspector python -m py_compile your_server.py npx @modelcontextprotocol/inspector

在 DeepCode 仓库中,MCP 运行时自身的测试覆盖了 test_mcp_runtime.py、test_mcp_runtime_lazy.py(延迟加载/按需激活)、test_mcp_oauth.py(OAuth 流程)等,可作为测试方法的参照样例。

十一、文档要求:让每个工具都可被发现、被信任

最佳实践文档对服务器作者提出的文档义务:

  • 清晰记录所有工具与能力
  • 每个主要功能至少 3 个可工作的示例
  • 记录安全注意事项;
  • 说明所需的权限与访问级别;
  • 记录限流(rate limits)与性能特征。

在 DeepCode 的消费端,工具描述会被截断至 8000 字符展示给模型(core/mcp/tools.py),服务器的 instructions 也有截断上限(server_instruction4000 字符、instruction_context8000 字符,见 core/mcp/runtime.py)——因此"描述要精炼、要点前置"不只是审美问题,而是直接影响模型可读性的工程约束。

十二、配套:用评估闭环检验 MCP 服务器质量

虽然评估细则在独立的 reference/evaluation.md 中,但它与本文档的"Testing Requirements"构成闭环。其核心理念值得在此强调:MCP 服务器的质量不以"实现了多少工具"衡量,而以"只给工具、不给其他上下文的情况下,LLM 能否借此回答真实且困难的问题"衡量。评估要求创建 10 道独立、只读、不可破坏、答案可字符串比对且随时间稳定(基于历史数据)的问题,并通过scripts/evaluation.py(支持-t stdio/sse/http-m指定模型、-o输出报告)运行得到准确率、平均耗时、平均工具调用数等指标。

结语

本文档所承载的规范——从{service}_{action}_{resource}命名、JSON/Markdown 双格式、分页元数据,到传输选型、安全加固、注解语义与测试/文档义务——构成了一个语言无关的"MCP 服务器质量底线"。在 DeepCode 中,这些规范既有 SKILL.md 层面的流程支撑,又有 core/mcp 运行时层面的强制落实(工具前缀化命名、注解按 hint 而非授权处理、凭据不入配置字面量、传输契约互斥校验),还有 core/mcp/presets.json 的真实预设作为参照。无论你是要编写一个全新的 MCP 服务器,还是要在 DeepCode 中接入第三方 MCP 服务,本文给出的规范与实现对照都可以直接作为设计评审清单使用。

【免费下载链接】DeepCode"DeepCode: Open Agentic Coding (Agent Harness & Loop Engineering & Multi-Agent Orchestration)"项目地址: https://gitcode.com/GitHub_Trending/deepc/DeepCode

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 10:59:14

在 Windows 上安装与管理 Vector 可观测性数据管道

在 Windows 上安装与管理 Vector 可观测性数据管道 【免费下载链接】vector A high-performance observability data pipeline. 项目地址: https://gitcode.com/GitHub_Trending/vect/vector 本指南面向需要在 Microsoft Windows 环境中部署 Vector 的运维与开发人员&am…

作者头像 李华
网站建设 2026/9/14 10:58:07

企业级AI编程平台选型落地指南:安全合规与效能度量

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 10:57:56

OpenGL多光源渲染实现与优化技巧

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华