名称:typescript-mcp 描述:| 当在Cloudflare Workers上使用TypeScript构建MCP(模型上下文协议)服务器时使用此技能。此技能提供生产测试的模式,用于使用官方@modelcontextprotocol/sdk实现工具、资源和提示。它防止10多种常见错误,包括导出语法问题、模式验证失败、未关闭传输导致的内存泄漏、CORS配置错误和认证漏洞。当开发人员需要无状态MCP服务器用于API集成、外部工具暴露或无服务器边缘部署时,应使用此技能。对于具有WebSocket和持久存储的有状态代理,请考虑使用Cloudflare Agents SDK。支持多种认证方法(API密钥、OAuth、零信任)、Cloudflare服务集成(D1、KV、R2、Vectorize)和全面的测试策略。与手动实现相比,生产测试可节省约70%的令牌。
关键词:mcp、模型上下文协议、typescript mcp、cloudflare workers mcp、mcp服务器、mcp工具、mcp资源、mcp sdk、@modelcontextprotocol/sdk、hono mcp、streamablehttpservertransport、mcp认证、mcp cloudflare、边缘mcp服务器、无服务器mcp、typescript mcp服务器、mcp api、llm工具、ai工具、cloudflare d1 mcp、cloudflare kv mcp、mcp测试、mcp部署、wrangler mcp、导出语法错误、模式验证错误、内存泄漏mcp、cors mcp、速率限制mcp 许可证:MIT 元数据: 版本:1.0.0 最后更新:2025-10-28 sdk版本:“@modelcontextprotocol/sdk@1.20.2” 平台:cloudflare-workers 生产测试:true 令牌效率:70% 错误防止:10+ 允许工具:[读取、写入、编辑、Bash、Grep、Glob]
在Cloudflare Workers上使用TypeScript构建MCP服务器
使用TypeScript构建生产就绪的Model Context Protocol(MCP)服务器,并将其部署在Cloudflare Workers上。此技能涵盖官方@modelcontextprotocol/sdk、HTTP传输设置、认证模式、Cloudflare服务集成和全面的错误预防。
何时使用此技能
在以下情况下使用此技能:
- 构建MCP服务器以向LLM暴露API、工具或数据
- 在Cloudflare Workers上部署无服务器MCP端点
- 集成外部API作为MCP工具(REST、GraphQL、数据库)
- 创建用于边缘部署的无状态MCP服务器
- 通过MCP协议暴露Cloudflare服务(D1、KV、R2、Vectorize)
- 实现具有API密钥、OAuth或零信任的认证MCP服务器
- 构建具有资源和提示的多工具MCP服务器
- 需要防止常见MCP错误的生产就绪模板
在以下情况下不要使用此技能:
- 构建Python MCP服务器(使用FastMCP技能)
- 需要具有WebSocket的有状态代理(使用Cloudflare Agents SDK)
- 需要具有SQLite存储的长时间运行持久代理(使用Durable Objects)
- 构建本地CLI工具(使用stdio传输,非HTTP)
核心概念
MCP协议组件
1. 工具 - LLM可以调用的函数
- 使用Zod定义输入/输出模式
- 异步处理程序返回结构化内容
- 可以调用外部API、数据库或计算
2. 资源 - 静态或动态数据暴露
- 基于URI的寻址(例如
config://app/settings) - 模板支持参数(例如
user://{userId}) - 返回文本、JSON或二进制数据
3. 提示 - 预配置的提示模板
- 提供可重复使用的对话启动器
- 可以包含占位符和动态内容
- 帮助标准化LLM交互
4. 补全(可选) - 参数自动补全
- 建议工具参数的有效值
- 改善开发者体验
快速开始
1. 基本MCP服务器模板
使用basic-mcp-server.ts模板实现最小工作服务器:
// 参见templates/basic-mcp-server.ts
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
import { Hono } from 'hono';
import { z } from 'zod';
const server = new McpServer({
name: 'my-mcp-server',
version: '1.0.0'
});
// 注册一个简单工具
server.registerTool(
'echo',
{
description: '回显输入文本',
inputSchema: z.object({
text: z.string().describe('要回显的文本')
})
},
async ({ text }) => ({
content: [{ type: 'text', text }]
})
);
// HTTP端点设置
const app = new Hono();
app.post('/mcp', async (c) => {
const transport = new StreamableHTTPServerTransport({
sessionIdGenerator: undefined,
enableJsonResponse: true
});
// 关键:在响应结束时关闭传输以防止内存泄漏
c.res.raw.on('close', () => transport.close());
await server.connect(transport);
await transport.handleRequest(c.req.raw, c.res.raw, await c.req.json());
return c.body(null);
});
export default app;
安装依赖:
npm install @modelcontextprotocol/sdk hono zod
npm install -D @cloudflare/workers-types wrangler typescript
部署:
wrangler deploy
2. 工具服务器模板
使用tool-server.ts暴露多个工具(API集成、计算):
// 示例:天气API工具
server.registerTool(
'get-weather',
{
description: '获取城市当前天气',
inputSchema: z.object({
city: z.string().describe('城市名称'),
units: z.enum(['metric', 'imperial']).default('metric')
})
},
async ({ city, units }, env) => {
const response = await fetch(
`https://api.openweathermap.org/data/2.5/weather?q=${city}&units=${units}&appid=${env.WEATHER_API_KEY}`
);
const data = await response.json();
return {
content: [{
type: 'text',
text: `${city}的温度:${data.main.temp}°${units === 'metric' ? 'C' : 'F'}`
}]
};
}
);
3. 资源服务器模板
使用resource-server.ts暴露数据:
import { ResourceTemplate } from '@modelcontextprotocol/sdk/types.js';
// 静态资源
server.registerResource(
'config',
new ResourceTemplate('config://app', { list: undefined }),
{ description: '应用程序配置' },
async (uri) => ({
contents: [{
uri: uri.href,
mimeType: 'application/json',
text: JSON.stringify({ version: '1.0.0', features: ['tool1', 'tool2'] })
}]
})
);
// 带参数的动态资源
server.registerResource(
'user-profile',
new ResourceTemplate('user://{userId}', { list: undefined }),
{ description: '用户配置文件数据' },
async (uri, { userId }, env) => {
const user = await env.DB.prepare('SELECT * FROM users WHERE id = ?').bind(userId).first();
return {
contents: [{
uri: uri.href,
mimeType: 'application/json',
text: JSON.stringify(user)
}]
};
}
);
4. 认证服务器模板
使用authenticated-server.ts实现生产安全:
import { Hono } from 'hono';
const app = new Hono();
// API密钥认证中间件
app.use('/mcp', async (c, next) => {
const authHeader = c.req.header('Authorization');
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return c.json({ error: '未授权' }, 401);
}
const apiKey = authHeader.replace('Bearer ', '');
const isValid = await c.env.MCP_API_KEYS.get(`key:${apiKey}`);
if (!isValid) {
return c.json({ error: '无效API密钥' }, 403);
}
await next();
});
app.post('/mcp', async (c) => {
// MCP服务器逻辑(用户已认证)
// ... 传输设置和处理
});
认证模式
模式1:API密钥(推荐用于大多数情况)
设置:
- 创建KV命名空间:
wrangler kv namespace create MCP_API_KEYS - 添加到
wrangler.jsonc:
{
"kv_namespaces": [
{ "binding": "MCP_API_KEYS", "id": "YOUR_NAMESPACE_ID" }
]
}
实现:
async function verifyApiKey(key: string, env: Env): Promise<boolean> {
const storedKey = await env.MCP_API_KEYS.get(`key:${key}`);
return storedKey !== null;
}
管理密钥:
# 添加密钥
wrangler kv key put --binding=MCP_API_KEYS "key:abc123" "true"
# 撤销密钥
wrangler kv key delete --binding=MCP_API_KEYS "key:abc123"
模式2:Cloudflare零信任访问
import { verifyJWT } from '@cloudflare/workers-jwt';
const jwt = c.req.header('Cf-Access-Jwt-Assertion');
if (!jwt) {
return c.json({ error: '访问被拒绝' }, 403);
}
const payload = await verifyJWT(jwt, c.env.CF_ACCESS_TEAM_DOMAIN);
// 用户通过Cloudflare Access认证
模式3:OAuth 2.0
完整OAuth实现参见references/authentication-guide.md。
Cloudflare服务集成
D1数据库工具示例
server.registerTool(
'query-database',
{
description: '在D1数据库上执行SQL查询',
inputSchema: z.object({
query: z.string(),
params: z.array(z.union([z.string(), z.number()])).optional()
})
},
async ({ query, params }, env) => {
const result = await env.DB.prepare(query).bind(...(params || [])).all();
return {
content: [{
type: 'text',
text: JSON.stringify(result.results, null, 2)
}]
};
}
);
Wrangler配置:
{
"d1_databases": [
{ "binding": "DB", "database_name": "my-db", "database_id": "..." }
]
}
KV存储工具示例
server.registerTool(
'get-cache',
{
description: '通过键检索缓存值',
inputSchema: z.object({ key: z.string() })
},
async ({ key }, env) => {
const value = await env.CACHE.get(key);
return {
content: [{ type: 'text', text: value || '未找到键' }]
};
}
);
R2对象存储工具示例
server.registerTool(
'upload-file',
{
description: '上传文件到R2存储桶',
inputSchema: z.object({
key: z.string(),
content: z.string(),
contentType: z.string().optional()
})
},
async ({ key, content, contentType }, env) => {
await env.BUCKET.put(key, content, {
httpMetadata: { contentType: contentType || 'text/plain' }
});
return {
content: [{ type: 'text', text: `文件已上传:${key}` }]
};
}
);
Vectorize搜索工具示例
server.registerTool(
'semantic-search',
{
description: '搜索向量数据库',
inputSchema: z.object({
query: z.string(),
topK: z.number().default(5)
})
},
async ({ query, topK }, env) => {
const embedding = await env.AI.run('@cf/baai/bge-base-en-v1.5', {
text: query
});
const results = await env.VECTORIZE.query(embedding.data[0], {
topK,
returnMetadata: true
});
return {
content: [{
type: 'text',
text: JSON.stringify(results.matches, null, 2)
}]
};
}
);
测试策略
1. 使用Vitest进行单元测试
import { describe, it, expect } from 'vitest';
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { z } from 'zod';
describe('计算器工具', () => {
it('应该将两个数字相加', async () => {
const server = new McpServer({ name: 'test', version: '1.0.0' });
server.registerTool(
'add',
{
description: '将两个数字相加',
inputSchema: z.object({
a: z.number(),
b: z.number()
})
},
async ({ a, b }) => ({
content: [{ type: 'text', text: String(a + b) }]
})
);
// 测试工具执行
const result = await server.callTool('add', { a: 5, b: 3 });
expect(result.content[0].text).toBe('8');
});
});
安装:
npm install -D vitest @cloudflare/vitest-pool-workers
运行:
npx vitest
2. 使用MCP检查器进行集成测试
# 本地运行服务器
npm run dev
# 在另一个终端中
npx @modelcontextprotocol/inspector
# 连接到:http://localhost:8787/mcp
3. 使用Claude Agent SDK进行端到端测试
完整测试模式参见references/testing-guide.md。
已知问题预防
此技能防止官方MCP SDK和Cloudflare仓库中记录的10多种生产问题:
问题#1:导出语法问题(关键)
错误:“无法读取未定义的属性(读取'map')”
来源:honojs/hono#3955, honojs/vite-plugins#237
原因:Vite构建中的错误导出格式导致神秘错误
预防:
// ❌ 错误 - 导致构建错误
export default { fetch: app.fetch };
// ✅ 正确 - 直接导出
export default app;
问题#2:未关闭的传输连接
错误:内存泄漏、挂起连接 来源:SDK维护者的最佳实践 原因:未在请求结束时关闭StreamableHTTPServerTransport 预防:
app.post('/mcp', async (c) => {
const transport = new StreamableHTTPServerTransport(/*...*/);
// 关键:始终在响应结束时关闭
c.res.raw.on('close', () => transport.close());
// ... 处理请求
});
问题#3:工具模式验证失败
错误:ListTools请求处理程序无法生成inputSchema
来源:GitHub modelcontextprotocol/typescript-sdk#1028
原因:Zod模式未正确转换为JSON模式
预防:
// ✅ 正确 - SDK自动处理Zod模式转换
server.registerTool(
'tool-name',
{
inputSchema: z.object({ a: z.number() })
},
handler
);
// 除非自定义验证,否则无需手动zodToJsonSchema()
问题#4:工具参数未传递给处理程序
错误:处理程序接收undefined参数
来源:GitHub modelcontextprotocol/typescript-sdk#1026
原因:注册和调用之间的模式类型不匹配
预防:
const schema = z.object({ a: z.number(), b: z.number() });
type Input = z.infer<typeof schema>;
server.registerTool(
'add',
{ inputSchema: schema },
async (args: Input) => {
// args.a和args.b正确类型化并传递
return { content: [{ type: 'text', text: String(args.a + args.b) }] };
}
);
问题#5:CORS配置错误
错误:浏览器客户端无法连接到MCP服务器 来源:常见生产问题 原因:HTTP传输缺少CORS头部 预防:
import { cors } from 'hono/cors';
app.use('/mcp', cors({
origin: ['http://localhost:3000', 'https://your-app.com'],
allowMethods: ['POST', 'OPTIONS'],
allowHeaders: ['Content-Type', 'Authorization']
}));
问题#6:缺少速率限制
错误:API滥用、DDoS漏洞 来源:生产安全最佳实践 原因:MCP端点无速率限制 预防:
app.post('/mcp', async (c) => {
const ip = c.req.header('CF-Connecting-IP');
const rateLimitKey = `ratelimit:${ip}`;
const count = await c.env.CACHE.get(rateLimitKey);
if (count && parseInt(count) > 100) {
return c.json({ error: '超过速率限制' }, 429);
}
await c.env.CACHE.put(
rateLimitKey,
String((parseInt(count || '0') + 1)),
{ expirationTtl: 60 }
);
// 继续...
});
问题#7:TypeScript编译内存问题
错误:tsc构建期间内存不足
来源:GitHub modelcontextprotocol/typescript-sdk#985
原因:MCP SDK中大型依赖树
预防:
# 添加到package.json脚本
"build": "NODE_OPTIONS='--max-old-space-size=4096' tsc && vite build"
问题#8:UriTemplate ReDoS漏洞
错误:服务器因恶意URI模式挂起 来源:GitHub modelcontextprotocol/typescript-sdk#965(安全) 原因:URI模板解析中的正则表达式拒绝服务 预防:更新到SDK v1.20.2或更高版本(包含修复)
问题#9:认证绕过
错误:未经授权访问MCP工具 来源:生产安全最佳实践 原因:缺少或不正确实现认证 预防:始终为生产服务器实施认证(参见认证模式部分)
问题#10:环境变量泄漏
错误:秘密在错误消息或日志中暴露 来源:Cloudflare Workers安全最佳实践 原因:环境变量被记录或返回在响应中 预防:
// ❌ 错误 - 暴露秘密
console.log('环境:', JSON.stringify(env));
// ✅ 正确 - 永不记录环境对象
try {
// ... 使用env.SECRET_KEY
} catch (error) {
// 不要在错误上下文中包含环境
console.error('操作失败:', error.message);
}
部署工作流程
本地开发
# 安装依赖
npm install
# 使用Wrangler本地运行
npm run dev
# 或
wrangler dev
# 服务器可用:http://localhost:8787/mcp
生产部署
# 构建
npm run build
# 部署到Cloudflare Workers
wrangler deploy
# 部署到特定环境
wrangler deploy --env production
使用GitHub Actions的CI/CD
名称:部署MCP服务器
触发:
推送:
分支:[main]
任务:
部署:
运行环境:ubuntu-latest
步骤:
- 使用:actions/checkout@v4
- 使用:actions/setup-node@v4
带:
node-version: '20'
- 运行:npm ci
- 运行:npm test
- 名称:部署到Cloudflare Workers
使用:cloudflare/wrangler-action@v3
带:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
包版本(验证于2025-10-28)
{
"依赖": {
"@modelcontextprotocol/sdk": "^1.20.2",
"@cloudflare/workers-types": "^4.20251011.0",
"hono": "^4.10.1",
"zod": "^3.23.8",
"zod-to-json-schema": "^3.24.1"
},
"开发依赖": {
"@cloudflare/vitest-pool-workers": "^0.5.29",
"vitest": "^3.0.0",
"wrangler": "^4.43.0",
"typescript": "^5.7.0"
}
}
何时使用Cloudflare Agents SDK替代
在以下情况使用Cloudflare Agents MCP:
- 具有持久存储的有状态代理(SQLite高达1GB)
- WebSocket支持用于实时双向通信
- 具有对话历史的长时间运行会话
- 具有Durable Objects警报的调度代理任务
- 具有自动状态复制的全局分布
在以下情况使用此技能(独立TypeScript MCP):
- 无状态工具和API集成
- 具有最小冷启动延迟的边缘部署
- 简单认证(API密钥、OAuth)
- 按请求付费定价(无Durable Objects开销)
- 最大可移植性(适用于任何平台,不仅Cloudflare)
详细比较参见references/cloudflare-agents-vs-standalone.md。
使用捆绑资源
模板(templates/)
所有模板都已生产测试并在Cloudflare Workers上测试:
templates/basic-mcp-server.ts- 最小工作服务器(回显工具示例)templates/tool-server.ts- 多工具实现(API集成、计算)templates/resource-server.ts- 仅资源服务器(静态和动态资源)templates/full-server.ts- 完整服务器(工具 + 资源 + 提示)templates/authenticated-server.ts- 具有API密钥认证的生产服务器templates/wrangler.jsonc- 具有所有绑定的Cloudflare Workers配置
当Claude应使用这些时:当创建新的MCP服务器时,基于用例复制适当的模板(仅工具、仅资源、认证或全功能)。
参考指南(references/)
高级主题的全面文档:
references/tool-patterns.md- 常见工具实现模式(API包装器、数据库查询、计算、文件操作)references/authentication-guide.md- 所有认证方法详细(API密钥、OAuth 2.0、零信任、JWT)references/testing-guide.md- 单元测试、使用MCP检查器的集成测试、使用Claude Agent SDK的端到端测试references/deployment-guide.md- Wrangler工作流程、环境管理、使用GitHub Actions的CI/CDreferences/cloudflare-integration.md- 使用D1、KV、R2、Vectorize、Workers AI、Queues、Durable Objectsreferences/common-errors.md- 所有10多种错误的详细解决方案、根本原因和预防策略references/cloudflare-agents-vs-standalone.md- 选择独立MCP和Cloudflare Agents SDK的决策矩阵
当Claude应加载这些时:当开发人员需要高级实现细节、调试帮助或架构指导时。
脚本(scripts/)
用于初始化和测试MCP服务器的自动化脚本:
scripts/init-mcp-server.sh- 使用依赖项、wrangler配置和模板选择初始化新MCP服务器项目scripts/test-mcp-connection.sh- 测试MCP服务器连接并验证工具/资源端点
当Claude应使用这些时:当设置新项目或调试连接问题时。
官方文档
- MCP规范:https://spec.modelcontextprotocol.io/
- TypeScript SDK:https://github.com/modelcontextprotocol/typescript-sdk
- Cloudflare Workers:https://developers.cloudflare.com/workers/
- Hono框架:https://hono.dev/
- Context7库ID:
/websites/modelcontextprotocol(如果可用)
示例服务器:
- 官方示例:https://github.com/modelcontextprotocol/servers
- Cloudflare MCP服务器:https://github.com/cloudflare/mcp-server-cloudflare
关键规则
始终做
✅ 在响应结束时关闭传输以防止内存泄漏
✅ 使用直接导出语法(export default app)而不是对象包装器
✅ 为生产服务器实施认证
✅ 添加速率限制以防止API滥用
✅ 使用Zod模式进行类型安全的工具定义
✅ 部署前使用MCP检查器测试
✅ 更新到SDK v1.20.2+以获取安全修复
✅ 使用清晰描述记录所有工具
✅ 优雅处理错误并返回有意义消息
✅ 对秘密使用环境变量(永不硬编码)
永不做
❌ 使用对象包装器导出(export default { fetch: app.fetch })
❌ 忘记关闭StreamableHTTPServerTransport
❌ 生产中部署无认证
❌ 记录环境变量或秘密
❌ 使用CommonJS格式(必须使用ES模块)
❌ 浏览器客户端跳过CORS配置
❌ 硬编码API密钥或凭据
❌ 返回原始错误对象(可能泄漏敏感数据)
❌ 未本地测试工具/资源就部署
❌ 使用具有已知漏洞的过时SDK版本
完整设置检查列表
使用此检查列表验证您的MCP服务器设置:
- [ ] SDK版本为1.20.2或更高
- [ ] 导出语法正确(直接导出,非对象包装器)
- [ ] 传输在响应结束时关闭
- [ ] 已实施认证(如果生产)
- [ ] 已配置速率限制(如果面向公众)
- [ ] 已设置CORS头部(如果浏览器客户端)
- [ ] 所有工具具有清晰描述和Zod模式
- [ ] 对秘密使用环境变量
- [ ] wrangler.jsonc包含所有必要绑定
- [ ] 本地测试
wrangler dev成功 - [ ] MCP检查器可以连接并列出工具
- [ ] 生产部署成功
- [ ] 所有工具/资源返回预期响应
生产示例
此技能基于以下模式:
- 官方MCP TypeScript SDK示例:https://github.com/modelcontextprotocol/servers
- Cloudflare MCP服务器:https://github.com/cloudflare/mcp-server-cloudflare
- 错误:0(所有10多种已知问题已预防)
- 令牌节省:约70%对比手动实现
- 验证:✅ 所有模板已在Cloudflare Workers上测试
问题?故障?
- 查看
references/common-errors.md进行故障排除 - 验证快速开始部分的所有步骤
- 使用MCP检查器测试:
npx @modelcontextprotocol/inspector - 查看官方文档:https://spec.modelcontextprotocol.io/
- 确保SDK版本为1.20.2或更高
最后更新:2025-10-28 SDK版本:@modelcontextprotocol/sdk@1.20.2 维护者:Claude技能仓库