如何从零开始构建 MCP Server (2026)
逐步创建自定义 Model Context Protocol 服务端
开始使用 Hypereal 构建
通过单个 API 访问 Kling、Flux、Sora、Veo 等。免费积分开始,扩展到数百万。
无需信用卡 • 10万+ 开发者 • 企业级服务
如何从零开始构建 MCP 服务器 (2026)
Model Context Protocol (MCP) 是由 Anthropic 创建的开放标准,旨在让 AI 助手通过统一接口连接到外部工具和数据源。你不再需要为每个 AI 客户端构建自定义集成,只需构建一个 MCP 服务器,它即可在 Claude Desktop、Cursor、VS Code 以及任何其他兼容 MCP 的客户端中运行。
本指南将通过 TypeScript 带你从零开始构建一个完整的 MCP 服务器。完成本指南后,你将拥有一台能够向任何 MCP 客户端提供自定义工具(tools)、资源(resources)和提示词(prompts)的运行服务器。
你将构建什么
我们将为一个假设的项目管理系统构建一个 MCP 服务器,其功能包括:
- 提供工具:供 AI 调用(创建任务、列出任务、更新状态)
- 提供资源:提供背景信息(项目数据、团队信息)
- 提供提示词:定义可复用的交互模式
前置条件
| 要求 | 详情 |
|---|---|
| Node.js | v18 或更高版本 |
| TypeScript | v5+ |
| npm 或 yarn | 用于包管理 |
| 基础 TypeScript 知识 | 函数、类型、async/await |
| MCP 客户端 | Claude Desktop、Cursor 或 VS Code |
第 1 步:初始化项目
创建一个新项目并安装 MCP SDK:
mkdir my-mcp-server
cd my-mcp-server
npm init -y
npm install @modelcontextprotocol/sdk zod
npm install -D typescript @types/node tsx
设置 TypeScript:
npx tsc --init
更新 tsconfig.json:
{
"compilerOptions": {
"target": "ES2022",
"module": "Node16",
"moduleResolution": "Node16",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"declaration": true
},
"include": ["src/**/*"]
}
更新 package.json 以添加构建脚本并设置类型:
{
"type": "module",
"scripts": {
"build": "tsc",
"start": "node dist/index.js",
"dev": "tsx src/index.ts"
},
"bin": {
"my-mcp-server": "./dist/index.js"
}
}
第 2 步:创建基础服务器
创建具有 MCP 服务器脚手架的 src/index.ts:
#!/usr/bin/env node
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
// 内存任务存储(生产环境请替换为数据库)
interface Task {
id: string;
title: string;
description: string;
status: "todo" | "in_progress" | "done";
assignee: string;
createdAt: string;
}
const tasks: Map<string, Task> = new Map();
let nextId = 1;
// 创建 MCP 服务器
const server = new McpServer({
name: "project-manager",
version: "1.0.0",
});
console.error("MCP server initialized"); // stderr 用于日志(stdout 用于 MCP 协议)
需要理解的关键点:MCP 服务器默认通过 stdio 通信。所有的协议消息都通过 stdout 传输,因此任何日志记录必须发送到 stderr。
第 3 步:添加工具 (Tools)
工具是 AI 助手可以调用的函数。它们是大多数 MCP 服务器的核心。将这些代码添加到 src/index.ts:
// 工具:创建新任务
server.tool(
"create_task",
"Create a new task in the project",
{
title: z.string().describe("The task title"),
description: z.string().describe("Detailed description of the task"),
assignee: z.string().describe("Name of the person assigned to the task"),
},
async ({ title, description, assignee }) => {
const id = `TASK-${nextId++}`;
const task: Task = {
id,
title,
description,
status: "todo",
assignee,
createdAt: new Date().toISOString(),
};
tasks.set(id, task);
return {
content: [
{
type: "text",
text: `Created task ${id}: "${title}" assigned to ${assignee}`,
},
],
};
}
);
// 工具:列出所有任务
server.tool(
"list_tasks",
"List all tasks, optionally filtered by status or assignee",
{
status: z
.enum(["todo", "in_progress", "done"])
.optional()
.describe("Filter by status"),
assignee: z.string().optional().describe("Filter by assignee name"),
},
async ({ status, assignee }) => {
let filtered = Array.from(tasks.values());
if (status) {
filtered = filtered.filter((t) => t.status === status);
}
if (assignee) {
filtered = filtered.filter((t) =>
t.assignee.toLowerCase().includes(assignee.toLowerCase())
);
}
if (filtered.length === 0) {
return {
content: [{ type: "text", text: "No tasks found matching the criteria." }],
};
}
const taskList = filtered
.map(
(t) =>
`- [${t.id}] ${t.title} (${t.status}) - Assigned to: ${t.assignee}`
)
.join("\n");
return {
content: [{ type: "text", text: taskList }],
};
}
);
// 工具:更新任务状态
server.tool(
"update_task_status",
"Update the status of an existing task",
{
taskId: z.string().describe("The task ID (e.g., TASK-1)"),
status: z
.enum(["todo", "in_progress", "done"])
.describe("The new status"),
},
async ({ taskId, status }) => {
const task = tasks.get(taskId);
if (!task) {
return {
content: [{ type: "text", text: `Task ${taskId} not found.` }],
isError: true,
};
}
const oldStatus = task.status;
task.status = status;
return {
content: [
{
type: "text",
text: `Updated ${taskId}: ${oldStatus} → ${status}`,
},
],
};
}
);
工具的结构
每个工具注册包含四个部分:
- 名称 (Name) —— AI 用来调用该工具的唯一标识符
- 描述 (Description) —— 告诉 AI 何时以及为什么要使用此工具
- 架构 (Schema) —— 定义参数的 Zod 架构(自动验证)
- 处理程序 (Handler) —— 执行工具并返回结果的异步函数
第 4 步:添加资源 (Resources)
资源为 AI 提供只读的背景信息。与工具不同,它们不执行动作,而是提供数据。
// 资源:项目摘要
server.resource(
"project-summary",
"project://summary",
async (uri) => {
const totalTasks = tasks.size;
const byStatus = {
todo: Array.from(tasks.values()).filter((t) => t.status === "todo").length,
in_progress: Array.from(tasks.values()).filter(
(t) => t.status === "in_progress"
).length,
done: Array.from(tasks.values()).filter((t) => t.status === "done").length,
};
const summary = `# Project Summary
Total tasks: ${totalTasks}
- To Do: ${byStatus.todo}
- In Progress: ${byStatus.in_progress}
- Done: ${byStatus.done}
Completion rate: ${totalTasks > 0 ? Math.round((byStatus.done / totalTasks) * 100) : 0}%`;
return {
contents: [
{
uri: uri.href,
mimeType: "text/markdown",
text: summary,
},
],
};
}
);
第 5 步:添加提示词 (Prompts)
提示词是 AI 客户端可以向用户提供的可复用模板。它们定义了结构化的交互模式:
// 提示词:迭代计划
server.prompt(
"sprint-planning",
"Generate a sprint planning summary based on current tasks",
{
sprintName: z.string().describe("Name of the sprint (e.g., Sprint 23)"),
},
async ({ sprintName }) => {
const todoTasks = Array.from(tasks.values()).filter(
(t) => t.status === "todo"
);
const taskListText =
todoTasks.length > 0
? todoTasks.map((t) => `- ${t.id}: ${t.title} (${t.assignee})`).join("\n")
: "No pending tasks.";
return {
messages: [
{
role: "user",
content: {
type: "text",
text: `Create a sprint planning document for "${sprintName}". Here are the current unassigned/todo tasks:\n\n${taskListText}\n\nPlease organize them by priority, estimate story points, and suggest a sprint goal.`,
},
},
],
};
}
);
第 6 步:启动服务器
在 src/index.ts 底部添加服务器启动代码:
// 启动服务器
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("Project Manager MCP server running on stdio");
}
main().catch((error) => {
console.error("Fatal error:", error);
process.exit(1);
});
构建并测试:
# 构建
npm run build
# 直接运行进行测试(你会看到服务器在 stdin 上等待 MCP 消息)
echo '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}},"id":1}' | node dist/index.js
第 7 步:连接到 Claude Desktop
将你的服务器添加到 Claude Desktop 的配置文件中。
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"project-manager": {
"command": "node",
"args": ["/绝对路径/到/my-mcp-server/dist/index.js"]
}
}
}
重启 Claude Desktop。你应该能看到工具图标显示你的 project-manager 服务器,并带有三个可用工具。
第 8 步:连接到 Cursor
对于 Cursor,在工作区根目录的 .cursor/mcp.json 中添加 MCP 服务器:
{
"mcpServers": {
"project-manager": {
"command": "node",
"args": ["/绝对路径/到/my-mcp-server/dist/index.js"]
}
}
}
重启 Cursor,这些工具将在 AI 聊天中可用。
测试你的服务器
MCP SDK 包含一个用于调试的检查器工具 (inspector):
npx @modelcontextprotocol/inspector node dist/index.js
这将打开一个 Web 界面,你可以在其中:
- 查看所有已注册的工具、资源和提示词
- 使用测试输入调用工具
- 查看原始 MCP 协议消息
- 实时调试错误
项目结构
你的最终项目应如下所示:
my-mcp-server/
src/
index.ts # 主服务器文件
dist/ # 编译输出
package.json
tsconfig.json
对于大型服务器,请拆分为独立文件:
my-mcp-server/
src/
index.ts # 服务器设置与启动
tools/
tasks.ts # 任务相关工具
reports.ts # 报告生成工具
resources/
project.ts # 项目资源
prompts/
planning.ts # 计划提示词模板
types.ts # 共享类型
dist/
package.json
tsconfig.json
常见模式
连接数据库
将内存中的 Map 替换为数据库客户端:
import Database from "better-sqlite3";
const db = new Database("./tasks.db");
db.exec(`
CREATE TABLE IF NOT EXISTS tasks (
id TEXT PRIMARY KEY,
title TEXT NOT NULL,
description TEXT,
status TEXT DEFAULT 'todo',
assignee TEXT,
created_at TEXT DEFAULT (datetime('now'))
)
`);
添加身份验证
如果你的 MCP 服务器需要访问外部 API,通过环境变量传递凭证:
{
"mcpServers": {
"project-manager": {
"command": "node",
"args": ["/path/to/dist/index.js"],
"env": {
"API_KEY": "your-secret-key",
"DATABASE_URL": "postgresql://localhost/mydb"
}
}
}
}
在你的服务器中访问它们:
const apiKey = process.env.API_KEY;
if (!apiKey) {
console.error("API_KEY environment variable is required");
process.exit(1);
}
总结
一旦你理解了三个原语:工具(动作)、资源(数据)和提示词(模板),构建 MCP 服务器就变得非常简单。MCP SDK 处理了所有的协议细节,因此你可以专注于对应用程序重要的逻辑。
MCP 正在迅速成为 AI 助手与外部世界交互的标准方式。构建你自己的服务器让你能够完全控制 AI 可以访问和执行的内容。
如果你的 AI 项目还涉及媒体生成(如图片、视频或语音头像),请查看 Hypereal AI,它提供涵盖所有主流 AI 媒体模型的统一 API。
免费试用 Hypereal AI —— 35 积分,无需信用卡。
