MCP服务器模板
用于构建模型上下文协议(MCP)服务器的生产就绪模板 Cloudflare Workers上的Clerk身份验证。此模板提供 创建安全、经过身份验证的MCP工具所需的一切 使用您现有的由Clerk驱动的应用程序。
特性
- ✅ 职员身份验证集成 -使用Clerk完成OAuth 2.0流程
- ✅ Cloudflare员工 -具有全球分布的无服务器边缘计算
- ✅ 耐用物品 -持续MCP会话状态管理
- ✅ KV存储 -临时OAuth会话存储
- ✅ 安全 -HMAC签名状态参数和自动令牌刷新
- ✅ TypeScript -整个代码库的完全类型安全
- ✅ 示例工具 -即用型示例MCP工具
- ✅ 开发工具 -ESLint、Prettier和MCP检查器集成
为什么是这个模板?
此模板将您现有的Clerk身份验证应用程序与Claude连接起来 通过MCP工具实现AI。非常适合:
- SaaS应用程序:允许Claude访问您的用户数据和业务逻辑
- 客户支持:让Claude使用适当的用户上下文查询您的系统
- 数据分析:为Claude提供对您的API的身份验证访问权限
- 工作流程自动化:创建安全的、用户特定的自动化
快速开始
1.先决条件
- Node.js 22.x或更高版本
- A. 职员 具有API密钥的帐户
- A. Cloudflare 的 启用Workers的帐户
- 使用Clerk进行身份验证的现有应用程序
2.使用此模板
git clone https://github.com/your-username/clerk-mcp-template.git my-mcp-server
cd my-mcp-server
npm install3.配置环境变量
复制示例环境文件:
cp .dev.vars.example .dev.vars更新 .dev.vars 使用您的职员密钥和应用程序URL:
CLERK_SECRET_KEY=sk_test_your_actual_clerk_secret_key
CLERK_PUBLISHABLE_KEY=pk_test_your_actual_clerk_publishable_key
APP_URL=https://your-app.com重要: APP_URL 应指向您已认证的现有职员 您将在其中实现MCP身份验证流的应用程序。4.创建KV命名空间
为OAuth会话存储创建KV命名空间:
wrangler kv:namespace create "OAUTH_KV"更新 id 在……里面 wrangler.jsonc 使用生成的命名空间ID。
5.更新配置
wrangler.jsonc:
- 改变
name从"your-mcp-server"到您想要的员工姓名 - 用上面生成的名称空间ID更新KV名称空间ID
src/index.ts:
- 更新中的服务器名称和版本
McpServer构造函数 - 用您自己的示例工具替换示例工具(见下面的示例)
6.开始开发
npm run dev服务器将在以下时间可用 http://localhost:8788
建筑
graph TB
A[MCP Client] --> B[Cloudflare Worker]
B --> C[OAuth Provider]
C --> D[Clerk Authentication]
B --> E[Durable Objects]
B --> F[KV Storage]
B --> G[Your API]
E --> H[MCP Session State]
F --> I[OAuth Sessions]
D --> J[User Authentication]
G --> K[Your Application Data]身份验证流程
- MCP客户端连接 向
/sse端点 - OAuth 重定向 向
/authorize端点 - 用户认证 通过职员(您执行此部分)
- 代币兑换 在
/callback端点 - 会话创建 在耐用物品中
- MCP工具 在经过身份验证的上下文中可用
与您的应用程序集成
步骤1:添加MCP身份验证路由
在现有的Clerk应用程序中创建身份验证路由 /auth/mcp此路由处理由MCP服务器发起的OAuth流。
React Router v7(框架模式)示例
此示例显示了在框架模式下与React Router v7的集成(以前 Remix),但你可以将其适应Next.js、Express或任何框架。
app/routes/auth.mcp.tsx:
import { createClerkClient } from '@clerk/express'
import { redirect, type LoaderFunctionArgs } from 'react-router'
export async function loader({ request }: LoaderFunctionArgs) {
const url = new URL(request.url)
const state = url.searchParams.get('state')
const callbackUrl = url.searchParams.get('callback_url')
const clientName = url.searchParams.get('client_name')
if (!state || !callbackUrl) {
throw new Error('Missing required parameters')
}
// Get the authenticated user's session token
const clerkClient = createClerkClient({
secretKey: process.env.CLERK_SECRET_KEY,
publishableKey: process.env.CLERK_PUBLISHABLE_KEY,
})
const clerkAuth = (await clerkClient.authenticateRequest(request)).toAuth()
const sessionToken = await clerkAuth?.getToken()
if (!sessionToken) {
// Redirect to sign-in if not authenticated
const signInUrl = new URL('/sign-in', request.url)
signInUrl.searchParams.set('redirect_url', request.url)
return redirect(signInUrl.toString())
}
// Redirect back to MCP server with token
const redirectUrl = new URL(callbackUrl)
redirectUrl.searchParams.set('clerk_token', sessionToken)
redirectUrl.searchParams.set('state', state)
return redirect(redirectUrl.toString())
}
// Optional: Add a component for showing consent screen
export default function McpAuth() {
return (
Authorize MCP Access
Claude AI is requesting access to your account data.
This will redirect you automatically...
)
}步骤2:创建API端点
在应用程序中添加受保护的API端点,MCP服务器可以调用这些端点 具有经过身份验证的请求。
app/routes/api.users.tsx:
import { createClerkClient } from '@clerk/express'
import { json, type LoaderFunctionArgs } from 'react-router'
export async function loader({ request }: LoaderFunctionArgs) {
try {
const clerkClient = createClerkClient({
secretKey: process.env.CLERK_SECRET_KEY,
publishableKey: process.env.CLERK_PUBLISHABLE_KEY,
})
// Verify the request is authenticated
const clerkAuth = await clerkClient.authenticateRequest(request)
const userId = clerkAuth.toAuth()?.userId
if (!userId) {
return json({ error: 'Unauthorized' }, { status: 401 })
}
// Your business logic here
const users = await getUsersForCurrentUser(userId)
return { users }
} catch (error) {
return json({ error: 'Internal server error' }, { status: 500 })
}
}步骤3:自定义MCP工具
更换中的示例工具 src/index.ts 用你自己的:
// Custom tool example
this.server.tool(
'getUsers',
'Fetch all users from your application',
{},
this.requireAuth(async () => {
const users = await this.makeApiRequest('api/users')
return {
content: [
{
type: 'text',
text: `Found ${users.length} users:\n${JSON.stringify(users, null, 2)}`,
},
],
}
}),
)配置参考
环境变量
| 变量 | 描述 | 必填 |
|---|---|---|
CLERK_SECRET_KEY | 您的职员密钥 | ✅ |
CLERK_PUBLISHABLE_KEY | 您的职员可发布密钥 | ✅ |
APP_URL | 您的应用程序URL | ✅ |
将您自己的特定于应用程序的环境变量添加到 Env 接口 在……里面 src/types.ts.
文员JWT模板
在您的职员仪表板中创建JWT模板以生成令牌:
- 首选 JWT模板 在您的职员仪表板中
- 创建新模板(例如“mcp服务器”)
- 更新中的模板名称
src/index.ts:
const token = await getToken(
// ... token manager
(this as any).env.CLERK_SECRET_KEY,
'your-template-name', // Update this
)发展
可用脚本
npm run dev # Start development server
npm run deploy # Deploy to Cloudflare Workers
npm run inspect # Launch MCP Inspector
npm run lint # Run ESLint + format
npm run typecheck # Run TypeScript type checking
npm run validate # Run typecheck + lintMCP检验员测试
- 启动开发服务器:
npm run dev - 打开 MCP检查员
- 将运输类型设置为 SSE
- 连接到
http://localhost:8788/sse - 完成身份验证流程
- 测试你的工具
部署
1.设定制作秘密
wrangler secret put CLERK_SECRET_KEY
wrangler secret put CLERK_PUBLISHABLE_KEY
wrangler secret put APP_URL2.创建生产KV命名空间
wrangler kv:namespace create "OAUTH_KV" --env production更新中的生产KV命名空间ID wrangler.jsonc.
3.部署和配置
npm run deploy将部署的服务器添加到Claude Desktop MCP配置中:
{
"mcpServers": {
"my-app": {
"command": "npx",
"args": [
"@modelcontextprotocol/server-remote",
"https://your-mcp-server.your-subdomain.workers.dev/sse"
]
}
}
}项目结构
clerk-mcp-template/
├── src/
│ ├── index.ts # Main MCP server class and tools
│ ├── auth.ts # OAuth authentication handlers
│ ├── clerk.ts # Clerk authentication utilities
│ ├── utils.ts # Utility functions (HMAC, logging, etc.)
│ └── types.ts # TypeScript type definitions
├── wrangler.jsonc # Cloudflare Worker configuration
├── package.json # Dependencies and scripts
├── tsconfig.json # TypeScript configuration
├── eslint.config.js # ESLint configuration
├── .dev.vars # Development environment variables
└── README.md # This file安全考虑
- OAuth 2.0 确保安全的身份验证流程
- HMAC签名 保护状态参数免受篡改
- 自动令牌刷新 处理会话过期
- 会话清理 删除过期的OAuth会话
- 安全标头 包含正确的CORS和身份验证标头
故障排除
常见问题
身份验证失败:
- 验证办事员API密钥是否正确
- 确保您的身份验证路由已实现
- 检查职员仪表板中是否存在JWT模板
KV命名空间错误:
- 验证中的命名空间ID
wrangler.jsonc - 确保命名空间已创建并绑定
工具不工作:
- 检查用户是否经过身份验证
- 验证API端点是否正确
- 查看Cloudflare Workers日志
调试
# View real-time logs
wrangler tail
# Check deployment status
wrangler deployments list
# Test locally with debugging
npm run dev贡献
- 分叉此存储库
- 创建要素分支:
git checkout -b feature/amazing-feature - 提交您的更改:
git commit -m 'Add amazing feature' - 推到分支:
git push origin feature/amazing-feature - 打开拉取请求
资源
许可证
MIT许可证-请参阅 许可证 文件以获取详细信息。
