2026 年,AI Agent 开发已经进入标准化时代。曾经,每个 AI 应用都需要为不同的 API、数据库和服务编写专属适配器——N 个模型 × M 个工具 = N×M 次重复工作。现在,Model Context Protocol (MCP) 提供了统一的解决方案。
本教程将带你从零开始,使用 TypeScript 构建一个完整的 MCP 服务器,实现:
- ✓ 可复用的工具函数库(搜索、数据库查询、文件操作)
- ✓ 动态资源暴露(让 AI 读取外部数据源)
- ✓ 预定义 Prompt 模板(标准化常见任务)
- ✓ 与主流 AI SDK(Vercel AI SDK、LangChain)无缝集成
一、MCP 核心概念速览
MCP 基于 JSON-RPC 2.0 协议,定义了三种核心原语:
二、环境准备
开始之前,确保你的开发环境满足以下要求:
三、实战步骤
初始化项目
创建新项目并安装依赖:
mkdir mcp-demo-server
cd mcp-demo-server
bun init -y
bun add @anthropic/mcp zod
bun add -d typescript @types/node
创建 tsconfig.json:
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"esModuleInterop": true,
"strict": true,
"skipLibCheck": true,
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src/**/*"]
}
创建 MCP 服务器骨架
在 src/server.ts 中创建基础服务器:
import { McpServer } from '@anthropic/mcp';
import { z } from 'zod';
const server = new McpServer({
name: 'demo-tool-server',
version: '1.0.0',
description: '一个展示 MCP 核心功能的示例服务器'
});
// 注册第一个工具
server.tool(
'hello',
'打招呼工具',
{
name: z.string().describe('要打招呼的人名')
},
async ({ name }) => {
return {
content: [
{ type: 'text', text: `你好,${name}!欢迎学习 MCP SDK` }
]
};
}
);
// 启动服务器
const transport = server.stdio();
console.log('MCP Server 已启动,等待客户端连接...');
实现实用工具:Web 搜索
添加工具函数,让 AI 能够进行实时网络搜索:
import { z } from 'zod';
server.tool(
'web-search',
'执行网络搜索并返回结果摘要',
{
query: z.string().describe('搜索关键词'),
numResults: z.number().default(5).describe('返回结果数量')
},
async ({ query, numResults }) => {
// 调用搜索 API(示例使用 Exa)
const response = await fetch('https://api.exa.ai/search', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.EXA_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
query,
numResults,
useAutoprompt: true
})
});
const data = await response.json();
return {
content: data.results.map((r: any) => ({
type: 'text',
text: `标题:${r.title}\n链接:${r.url}\n摘要:${r.text}`
}))
};
}
);
暴露资源:数据库查询接口
让 AI 能够读取外部数据源:
import { ResourceTemplate } from '@anthropic/mcp';
server.resource(
'user-data',
new ResourceTemplate('userdata://{userId}', {
list: async () => ({
resources: [
{ uri: 'userdata://profile', name: '用户资料' },
{ uri: 'userdata://orders', name: '订单历史' }
]
})
}),
async (uri, params) => {
// 从数据库获取数据
const userId = params.userId;
const db = await connectToDatabase();
const userData = await db.query(
'SELECT * FROM users WHERE id = $1',
[userId]
);
return {
contents: [{
uri: uri.href,
mimeType: 'application/json',
text: JSON.stringify(userData.rows[0], null, 2)
}]
};
}
);
创建 Prompt 模板
预定义常见任务的指令模板:
server.prompt(
'code-review',
'代码审查助手',
{
code: z.string().describe('要审查的代码'),
language: z.string().default('typescript').describe('编程语言')
},
({ code, language }) => ({
messages: [{
role: 'user',
content: {
type: 'text',
text: `请审查以下 ${language} 代码:
${code}
请检查:
1. 代码风格和最佳实践
2. 潜在的性能问题
3. 安全漏洞
4. 可维护性改进建议`
}
}]
})
);
配置传输层:SSE 模式
生产环境使用 HTTP+SSE 传输:
import express from 'express';
import { SSEServerTransport } from '@anthropic/mcp/sse';
const app = express();
app.post('/sse', async (req, res) => {
const transport = new SSEServerTransport('/messages', res);
await server.connect(transport);
});
app.post('/messages', async (req, res) => {
await transport.handlePostMessage(req, res);
});
app.listen(3000, () => {
console.log('MCP SSE Server running on http://localhost:3000');
});
客户端集成:Vercel AI SDK
在 AI 应用中使用你的 MCP 服务器:
import { createMcpClient } from 'ai/mcp';
import { streamText } from 'ai';
// 连接到本地 MCP 服务器
const client = await createMcpClient({
command: 'bun',
args: ['run', 'src/server.ts']
});
// 获取可用工具
const tools = await client.tools();
// 使用工具执行任务
const result = streamText({
model: yourModel,
messages: [{ role: 'user', content: '帮我搜索最新 MCP 教程' }],
tools
});
// 消费流式响应
for await (const chunk of result.textStream) {
process.stdout.write(chunk);
}
调试与测试
使用 MCP Inspector 进行调试:
# 安装 MCP Inspector
bun add -d @anthropic/mcp-inspector
# 启动 Inspector
bun x @anthropic/mcp-inspector \
--command bun \
--args "run,src/server.ts"
Inspector 提供可视化界面,可以:
- 查看注册的 Tools、Resources、Prompts
- 手动调用工具并查看返回结果
- 检查 JSON-RPC 消息往来
四、常见问题 FAQ
Q: MCP 和传统的 REST API 有什么区别?
A: REST API 是静态的、预定义的接口,需要开发者手动编写调用逻辑。MCP 是动态的、自描述的——服务器会主动向 AI 暴露可用工具清单,AI 可以根据任务目标自主选择工具。这大大降低了集成成本。
Q: 如何保证 MCP 工具调用的安全性?
A: 关键措施包括:(1) 所有工具参数用 Zod 做严格校验;(2) 敏感操作添加权限验证;(3) 记录所有工具调用日志;(4) 对 AI 的输入做 prompt injection 检测;(5) 资源访问限制在只读范围。
Q: MCP 服务器可以部署到哪些环境?
A: 支持所有 Node.js/Bun 运行环境:本地开发用 stdio 模式,Docker 容器、Vercel/Cloudflare 等云函数、甚至浏览器(通过 WebSocket)都可以运行 MCP 服务器。
Q: 如何处理长时间运行的工具?
A: 使用 MCP 的 progress 通知机制,在工具执行过程中定期发送进度更新。对于超长任务,可以设计为异步模式——工具立即返回任务 ID,客户端通过资源轮询结果。
五、总结
- ✓ MCP 解决了 AI 与外部工具集成的标准化问题
- ✓ 三种原语:Tools(执行动作)、Resources(读取数据)、Prompts(模板指令)
- ✓ 使用 @anthropic/mcp SDK 可快速搭建服务器
- ✓ 支持 stdio 和 SSE 两种传输模式
- ✓ 与 Vercel AI SDK、LangChain 等主流框架无缝对接