一个最小化的、生产就绪的TypeScript模板,用于构建模型上下文协议(MCP)服务器。
</div>模型上下文协议(MCP)是一个开放协议,标准化了AI应用程序如何连接到数据源和工具。可以将其视为“AI的USB-C”——一种通用标准,允许任何AI模型通过一致的接口与任何数据源或工具进行连接。
graph LR
A[AI] <-->|MCP| B[Server]
B <--> C[Tools]
B <--> D[Resources]
此启动模板提供:
无论您是为数据库、API、文件系统或自定义业务工具构建集成,此模板都能帮助您创建可用于任何MCP兼容客户端(如Claude桌面、IDE或自定义应用)的MCP服务器。
[!重要] 在继续之前,请确保已安装Node.js版本20.11.0或更高版本。
# 克隆仓库
git clone https://github.com/alexanderop/mcp-server-starter-ts.git
cd mcp-server-starter-ts
# 安装依赖项
npm install
# 构建项目
npm run build
您也可以将此用作GitHub模板:
[!提示] 开发期间使用MCP Inspector交互式地测试您的服务器!
构建服务器:
npm run build
使用MCP Inspector测试:
npm run inspect
这将打开MCP Inspector,在那里您可以与服务器的工具、资源和提示进行交互。
运行测试:
npm test
此服务器支持两种传输模式:stdio(默认)和HTTP(流式SSE + JSON-RPC)。
传统的stdio传输适用于本地开发和桌面客户端:
# 使用stdio传输运行
npm run serve:stdio
# 或者简单地(默认为stdio)
npm run build && node build/index.js
流式HTTP传输适用于Web部署和远程访问:
# 在端口3000上使用HTTP传输运行
npm run serve:http
# 使用MCP Inspector测试
npm run inspect:http
HTTP传输暴露:
http://localhost:3000/mcp - 用于服务器发送事件http://localhost:3000/mcp - 用于请求使用环境变量配置服务器行为:
| 变量 | 描述 | 默认值 |
|---|---|---|
STARTER_TRANSPORT | 传输模式:stdio 或 http | stdio |
PORT | HTTP服务器端口(仅限HTTP模式) | 3000 |
CORS_ORIGIN | CORS允许的来源(仅限HTTP模式) | * |
mcp.json 或 .vscode/mcp.json){
"servers": {
"starter-stdio": {
"type": "stdio",
"command": "node",
"args": ["./build/index.js"]
},
"starter-http": {
"type": "http",
"url": "http://localhost:3000/mcp"
}
}
}
添加到您的Claude Desktop配置:
{
"mcpServers": {
"mcp-server-starter": {
"command": "node",
"args": ["/path/to/mcp-server-starter/build/index.js"]
}
}
}
服务器包括Docker支持,便于部署:
# 使用Docker Compose构建并运行
docker compose up --build
# 或运行预构建的镜像
docker run -p 3000:3000 ghcr.io/alexanderopalic/mcp-server-starter-ts:latest
Docker容器默认在HTTP模式下运行。使用环境变量覆盖设置:
docker run -p 3000:3000 \
-e CORS_ORIGIN="https://example.com" \
-e PORT=3000 \
ghcr.io/alexanderopalic/mcp-server-starter-ts:latest
使用开发配置文件进行热重载:
docker compose --profile dev up mcp-server-starter-dev
这将挂载您的源代码,并在端口3001启用实时重载。
mcp-server-starter-ts/
├── src/
│ ├── index.ts # 主入口点
│ ├── registry/ # 自动加载系统
│ │ ├── auto-loader.ts # 模块自动发现
│ │ └── types.ts # TypeScript接口
│ ├── tools/ # 工具实现
│ │ └── echo.ts # 示例回声工具
│ ├── resources/ # 资源实现(默认为空)
│ └── prompts/ # 提示实现(默认为空)
├── tests/ # 测试文件
├── _templates/ # Hygen生成器模板
│ ├── tool/new/ # 工具生成器
│ ├── prompt/new/ # 提示生成器
│ └── resource/new/ # 资源生成器
├── build/ # 编译的JavaScript(生成)
├── mcp.json # MCP服务器配置
├── package.json # Node.js依赖项
├── tsconfig.json # TypeScript配置
├── eslint.config.js # ESLint配置
└── README.md
flowchart TB
A[开始] --> B[扫描]
B --> C[注册]
C --> D[准备就绪]
[!提示] 只需将模块文件放入适当的目录(
tools/、resources/或prompts/)中,当服务器启动时,它们将被自动加载!
[!提示] 使用内置的Hygen生成器创建新模块最快捷的方式!
该项目包括Hygen脚手架,用于快速模块创建。每个生成器都会创建实现文件和相应的测试文件。
npm run gen:tool
您将被提示:
text-transform)npm run gen:prompt
您将被提示:
code-review)npm run gen:resource
您将被提示:
app-status)您还可以直接提供参数:
npx hygen tool new --name my-tool --description "执行有用的操作"
npx hygen prompt new --name my-prompt --description "生成有用的文本"
npx hygen resource new --name my-resource --description "提供数据"
生成的文件:
src/{tools|prompts|resources}/[name].tstests/[name].test.ts自动加载器会自动发现并注册所有生成的模块——无需额外配置!
graph TD
A[MCP] --> B[工具]
A --> C[资源]
A --> D[提示]
[!注意] 工具是AI可以调用来执行特定操作或计算的函数。
工具允许您的MCP服务器执行操作。在src/tools/中创建新文件:
// src/tools/calculate.ts
import { z } from "zod";
import type { RegisterableModule } from "../registry/types.js";
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
const calculateModule: RegisterableModule = {
type: "tool",
name: "calculate",
description: "执行基本算术运算",
register(server: McpServer) {
server.tool(
"calculate",
"执行基本算术运算",
{
operation: z.enum(["add", "subtract", "multiply", "divide"])
.describe("要执行的算术运算"),
a: z.number().describe("第一个数字"),
b: z.number().describe("第二个数字"),
},
(args) => {
let result: number;
switch (args.operation) {
case "add": result = args.a + args.b; break;
case "subtract": result = args.a - args.b; break;
case "multiply": result = args.a * args.b; break;
case "divide":
if (args.b === .0) throw new Error("除以零");
result = args.a / args.b;
break;
}
return {
content: [
{
type: "text",
text: `结果: ${result}`,
},
],
};
}
);
}
};
export default calculateModule;
[!注意] 资源提供只读的数据,可以被AI客户端消费。
资源提供可以由客户端读取的数据。在src/resources/中创建新文件:
// src/resources/config.ts
import type { RegisterableModule } from "../registry/types.js";
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
const configResource: RegisterableModule = {
type: "resource",
name: "config",
description: "应用程序配置",
register(server: McpServer) {
server.resource(
"config://app/settings",
"应用程序设置",
"application/json",
async () => {
const settings = {
version: "1.0.0",
environment: process.env.NODE_ENV || "development",
features: {
autoSave: true,
darkMode: false,
}
};
return {
contents: [
{
uri: "config://app/settings",
mimeType: "application/json",
text: JSON.stringify(settings, null, 2),
}
]
};
}
);
}
};
export default configResource;
[!注意] 提示是可重复使用的模板,有助于与AI模型进行互动。
提示是可重复使用的提示模板。在src/prompts/中创建新文件:
// src/prompts/code-review.ts
import { z } from "zod";
import type { RegisterableModule } from "../registry/types.js";
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
const codeReviewPrompt: RegisterableModule = {
type: "prompt",
name: "code-review",
description: "生成代码审查提示",
register(server: McpServer) {
server.prompt(
"code-review",
"生成全面的代码审查",
{
language: z.string().describe("编程语言"),
code: z.string().describe("要审查的代码"),
focus: z.string().optional().describe("要关注的具体区域"),
},
(args) => {
return {
messages: [
{
role: "user",
content: {
type: "text",
text: `请审查以下${args.language}代码:
\`\`\`${args.language}
${args.code}
\`\`\`
${args.focus ? `关注区域:${args.focus}` : ""}
请提供:
1. 代码质量评估
2. 潜在的错误或问题
3. 性能考虑
4. 安全性问题
5. 改进建议`,
},
},
],
};
}
);
}
};
export default codeReviewPrompt;
MCP Inspector是一款强大的测试工具:
npm run inspect
此命令:
为了快速测试和开发,使用交互式开发模式:
npm run dev
这将启动一个交互式REPL,您可以在其中直接粘贴JSON-RPC消息并实时查看响应。非常适合在开发过程中测试您的MCP服务器!
一旦运行npm run dev,您可以直接粘贴这些JSON-RPC消息。
[!重要] 需要MCP协议握手
在使用工具、资源或提示之前,MCP协议要求特定的初始化序列:
- 初始化请求 - 客户端发送能力并接收服务器能力
- 初始化通知 - 客户端确认它已准备好(不期望响应)
为什么需要初始化通知?
- 它确认客户端已处理初始化响应并准备好
- 它使双向通信成为可能 - 在此之后,服务器可以向客户端发送请求
- 没有它,服务器不会发送通知(如
tools/list_changed)或请求(如sampling/createMessage)- 这遵循类似于TCP握手的模式,确保双方在实际通信开始前都已准备好
开发服务器不会自动执行此握手。您必须首先手动发送这些消息。
步骤1 - 发送初始化请求:
{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"1.0.0","capabilities":{},"clientInfo":{"name":"dev-client","version":"1.0.0"}},"id":1}
步骤2 - 接收响应后,发送初始化通知:
{"jsonrpc":"2.0","method":"notifications/initialized"}
现在服务器准备好处理请求!
{"jsonrpc":"2.0","method":"tools/list","params":{},"id":2}
{"jsonrpc":"2.0","method":"tools/call","params":{"name":"echo","arguments":{"text":"你好,M