这两年被问到最多的一个问题,基本都绕不开“怎么让AI不光会聊天,还能真的帮我干活”。答案其实很明确:给模型配上工具。而MCP(Model Context Protocol)就是当前最有希望把“配工具”这件事标准化的协议,MCP Server则是承载具体工具的服务端程序。简单说,Claude、Cursor、各类AI Agent平台通过这套协议连上你的MCP Server,就能调用你暴露出来的查询、写入、计算等能力,从单纯的语言模型变成一个能真正操作的智能体。
MCP Server本身跑起来不难,官方SDK把协议细节封装得很干净,写一个hello world级别的工具撑死二十行代码。可只要工具数量一多、场景一复杂,问题就全冒出来了:代码全堆在入口文件里、工具命名随缘、参数Schema复制粘贴、错误处理五花八门、被两个Host同时拉起就会出各种诡异故障。这篇文章是我在落地几个AI工具中枢项目之后做的工程结构复盘,从目录划分、工具实现规范、可观测性、安全控制、测试部署到高频踩坑点,是一套可以直接照着改的实践方案,适合正在从demo走向生产环境的MCP Server维护者。
1. 先把问题说清楚:MCP Server 为什么要谈“工程结构”
1.1 MCP Server 到底是干什么的
MCP协议把“AI模型调用外部工具”这件事做了一次标准化抽象。整个体系里有三个角色:AI应用是Host,Host内部维护了Client,而MCP Server是实际执行工具的服务端。用户跟AI说“帮我查一下订单状态”,模型不直接查数据库,而是通过Client向MCP Server发送一个工具调用请求,工具执行完把结果返回给模型,模型再组织语言回复用户。
MCP Server向外暴露的核心能力有三类:工具(Tools)、资源(Resources)、提示词(Prompts)。但实际用得最多、最核心的一定是工具。资源相当于给模型提供可读取的上下文片段,提示词相当于复用一些指令模板,而工具才是让模型“动手”的接口。协议底层基于JSON-RPC 2.0,关键方法就是initialize握手、tools/list拉取工具清单、tools/call调用具体工具。Host和Server之间既可以通过stdio进程间通信,也可以通过HTTP远程连接。
拿生活里的场景打比方,MCP Server就是AI的万能工具箱管理员。模型知道工具箱里有哪些工具、每个工具是干什么的、用的时候要填什么参数,但工具本身放在Server这边。这种解耦最大的价值在于:一套工具实现,可以被任何支持MCP的AI应用复用。我在本地写好一个企业知识库查询Server,Claude Desktop能用,Cursor能用,后面接Dify、自研Agent平台也能用,不用每个平台单独适配一遍。
1.2 “能跑”和“工业级”之间差了什么
先说个我踩过的真实案例。早期我做了一个MCP Server,专门给AI加文件搜索和网页抓取工具,当时只有一个入口文件,所有逻辑全写在里面。跑起来确实没问题,Claude Desktop连上之后也能调。但后来要加数据库查询工具,代码开始失控;再后来要让同事的Agent平台也能连,问题彻底爆发:工具注册散落在各个函数里,想查一下有哪些工具只能靠人肉翻代码;一个工具报错,整个Server进程被异常拖垮;日志全是console.log,模型调用失败根本不知道是参数问题还是逻辑问题。
把MCP Server当成生产系统来看,“能跑”和“工业级”之间起码差四件事。第一是可维护性,代码结构清晰,加新工具不改旧逻辑,删除工具不留垃圾代码。第二是可观测性,每次工具调用都有日志、有耗时、有成功失败标记,出问题能快速定位。第三是可控制性,谁在调用、能调哪些工具、敏感操作要不要人工确认,这些都有闸门。第四是可恢复性,工具偶发超时、外部API抖动、进程异常退出,都要有兜底策略,而不是整个Server跟着一起挂掉。
工程结构是这一切的地基。目录分得不清楚,后续所有规范都无处安放;工具定义和业务逻辑不分离,可观测性和安全控制就只能靠复制粘贴。所以这篇文章虽然聊的是结构,本质上聊的是MCP Server的生命周期管理。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 目录结构设计:一份可以直接抄走的骨架
2.1 核心分层思想:入口、协议、业务、横切关注点
我在多个项目里反复调整后,目前稳定使用的一套目录结构长这样:
text复制mcp-tool-hub/
├── src/
│ ├── index.ts # 入口:负责启动Server
│ ├── config/
│ │ ├── index.ts # 配置加载与环境变量解析
│ │ └── schema.ts # 配置项运行时校验
│ ├── domain/ # 业务域,按领域拆目录
│ │ ├── user/
│ │ │ ├── tools/
│ │ │ │ ├── getUser.ts
│ │ │ │ └── updateUser.ts
│ │ │ └── service.ts
│ │ └── order/
│ │ ├── tools/
│ │ └── service.ts
│ ├── mcp/ # 协议层:与业务无关
│ │
