第 02 模块 · 3 节

构建自定义 MCP Server

《Claude Code 生产级工程》02 MCP 服务集成 · 本节时长 44 分钟

没有现成的?自己写一个

接外部服务时,如果没有现成的 MCP Server,或现成的不符合需求,就要自己写一个。别怕——大多数情况你写的只是一个薄薄的适配器:把内部服务的接口「翻译」成 MCP 协议,让模型能调用。

贯穿项目上一节 mcp-hub 接的是「现成 Server」。这一节,你给 mcp-hub **自建一个它专属的 Server**——接入一个没有现成适配器的内部服务(比如团队的内部 API)。mcp-hub 的价值从此升级:**它不仅能管现成的,还能长出「为自己量身定制」的接入能力。**

自定义 MCP Server 在做什么

它的本质是一层翻译:

模型(Claude Code)  ←MCP协议→  你的 Server  ←内部调用→  你的服务/数据

你负责实现:模型说一句请求 → Server 翻译 → 调你的服务 → 把结果翻译回模型。

给 mcp-hub 自建 Server 时,这层翻译就是 mcp-hub 连接「没有现成适配器」服务的桥梁。你写的不是整个服务,而是一个让 Claude Code 能和你内部服务说话的小翻译官


一个 Server 的核心组成

写一个 MCP Server,通常要提供:

部分 作用
工具定义 暴露哪些能力、参数是什么、返回什么
处理逻辑 收到调用后,怎么调你的服务
错误处理 服务失败时,返回可理解的错误

拿「查内部订单服务」举例:

工具:query_orders
参数:start_date, end_date, status
逻辑:调内部 API 拿订单
返回:订单列表 + 总金额

给 mcp-hub 自建 Server 时,工具定义尤其要克制:每个工具都对应一个真实、明确的内部能力,别为了「齐全」而堆一堆内部都还没理清的操作。


开发流程:先小后全

  1. 先接一个工具:只实现最核心的一个能力
  2. 手工验证:直接调 Server,看返回对不对
  3. 再扩展:稳定了再加更多工具

别一上来就做一整套。最小可用,逐步迭代,和写插件一样。

对 mcp-hub 的自建 Server:第一版只做「查订单」这一个工具。把这一个工具从「模型请求」到「内部 API」再到「返回结果」整条走通,验证稳定了,再加「查库存」「查用户」……一次一个。


开发时要特别注意的三点

1. 鉴权

内部服务需要认证,你的 Server 要处理好:用什么凭据、怎么安全传递、别把密钥泄露给模型。

对 mcp-hub:服务端凭据和模型可见信息要彻底隔离。模型可能看不到也不该看到你调内部 API 用的密钥。

2. 超时与限流

外部服务可能慢、可能限流。你的 Server 要:

  • 设置合理的超时,别让模型干等
  • 处理限流,返回清晰提示

3. 返回结构稳定

返回给模型的数据结构要稳定、可预期。变来变去,模型没法可靠使用。

对 mcp-hub:返回结构稳定尤其重要,因为 mcp-hub 是团队共享的——结构一乱,全团队调用它的下游都受影响。


一个可复制的 Server 骨架

下面是自建 Server 的核心骨架思路,照着补内部逻辑即可:

# 骨架:一个「只读查询」的 MCP Server
from mcp.server import Server  # 以你所用 SDK 为准

app = Server("mcp-hub-internal")

@app.tool()  # 定义一个工具
def query_orders(start_date: str, end_date: str) -> str:
    # 1. 鉴权:用环境变量里的内部密钥
    # 2. 调内部 API 拿订单
    # 3. 按稳定结构返回(列表 + 总金额)
    return json.dumps({"ok": True, "orders": [], "total": 0})

if __name__ == "__main__":
    app.run()

注意:SDK 的写法以你所用版本为准,这里给你的是结构——工具定义、处理逻辑、返回结构三块,缺一不可。


落地练习:给 mcp-hub 自建一个「只读」Server

这一节,给 mcp-hub 自建它专属的第一个 Server。

跟着这三步走:

  1. 选一个没有现成适配器的内部服务(比如内部 API),先手工调通它的接口
  2. 用上面的骨架,实现一个只读工具,走通「模型请求 → 内部 API → 返回」
  3. 通过 mcp-hub 注册它,用自然语言让 Claude Code 实际调用一次

你会怎么判断做对了?——Claude Code 通过你自建的 Server 拿到了内部服务的真实数据,返回结构稳定、鉴权用环境变量、且只暴露了你定义的那一个工具,就算过关。

卡住了怎么办? SDK 不会用?先只看官方示例把最小 Server 跑起来,再补你的逻辑。内部 API 连不通?先手工 curl 确认接口本身可用,再怀疑 Server。结构拿不准?先固定一个简单的 JSON 结构,稳定了再丰富。


常见坑:一个 Server 里塞了太多工具

给 mcp-hub 自建 Server 时,最常见的坑是「顺手把内部服务的全部能力都做成工具」——想着反正都在一个 Server 里,多一个少一个没差。

但每个工具都是一份风险面:模型可能误触、维护要跟、出问题要排查。 正确做法是「先少后多,需要再加」。第一版只做那个「团队真正会反复用」的工具,跑稳了再扩展。一个 Server 里工具越少,越安全、越好维护、越好让 Claude Code 稳定选用。


小结

  1. 自定义 Server = 薄薄一层翻译:内部服务 → MCP 协议
  2. 核心:工具定义 + 处理逻辑 + 错误处理
  3. 先做一个工具、手工验证、再扩展
  4. 重点:鉴权、超时限流、返回结构稳定;只暴露必要工具
  5. mcp-hub 从此能「为自己量身定制」接入能力

下一节,讲 Server 的安全与错误处理。