Clerk MCP Server Template

Clerk MCP Server Template

A production-ready template for building Model Context Protocol servers with Clerk authentication on Cloudflare Workers, allowing AI assistants to securely access user data and business logic in Clerk-authenticated applications.

Category
访问服务器

README

Clerk MCP Server Template

A production-ready template for building Model Context Protocol (MCP) servers with Clerk authentication on Cloudflare Workers. This template provides everything you need to create secure, authenticated MCP tools that integrate with your existing Clerk-powered applications.

Features

  • Clerk Authentication Integration - Complete OAuth 2.0 flow with Clerk
  • Cloudflare Workers - Serverless edge computing with global distribution
  • Durable Objects - Persistent MCP session state management
  • KV Storage - Temporary OAuth session storage
  • Security - HMAC-signed state parameters and automatic token refresh
  • TypeScript - Full type safety throughout the codebase
  • Example Tools - Ready-to-use example MCP tools
  • Development Tools - ESLint, Prettier, and MCP Inspector integration

Why This Template?

This template bridges your existing Clerk-authenticated application with Claude AI through MCP tools. Perfect for:

  • SaaS Applications: Give Claude access to your user data and business logic
  • Customer Support: Let Claude query your systems with proper user context
  • Data Analysis: Provide Claude with authenticated access to your APIs
  • Workflow Automation: Create secure, user-specific automations

Quick Start

1. Prerequisites

  • Node.js 22.x or later
  • A Clerk account with API keys
  • A Cloudflare account with Workers enabled
  • An existing application using Clerk for authentication

2. Use This Template

git clone https://github.com/your-username/clerk-mcp-template.git my-mcp-server
cd my-mcp-server
npm install

3. Configure Environment Variables

Copy the example environment file:

cp .dev.vars.example .dev.vars

Update .dev.vars with your Clerk keys and app 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

Important: APP_URL should point to your existing Clerk-authenticated application where you'll implement the MCP auth flow.

4. Create KV Namespace

Create a KV namespace for OAuth session storage:

wrangler kv:namespace create "OAUTH_KV"

Update the id in wrangler.jsonc with the generated namespace ID.

5. Update Configuration

wrangler.jsonc:

  • Change name from "your-mcp-server" to your desired worker name
  • Update the KV namespace ID with the one generated above

src/index.ts:

  • Update the server name and version in the McpServer constructor
  • Replace example tools with your own (see examples below)

6. Start Development

npm run dev

The server will be available at http://localhost:8788

Architecture

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]

Authentication Flow

  1. MCP Client connects to /sse endpoint
  2. OAuth redirect to /authorize endpoint
  3. User authentication via Clerk (you implement this part)
  4. Token exchange at /callback endpoint
  5. Session creation in Durable Objects
  6. MCP tools become available with authenticated context

Integrating with Your Application

Step 1: Add MCP Authentication Route

Create an authentication route in your existing Clerk application at /auth/mcp. This route handles the OAuth flow initiated by the MCP server.

React Router v7 (Framework Mode) Example

This example shows integration with React Router v7 in framework mode (formerly Remix), but you can adapt it to Next.js, Express, or any framework.

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 (
		<div className="max-w-md mx-auto mt-8 p-6 bg-white rounded-lg shadow-md">
			<h1 className="text-xl font-bold mb-4">Authorize MCP Access</h1>
			<p className="text-gray-600 mb-4">
				Claude AI is requesting access to your account data.
			</p>
			<p className="text-sm text-gray-500">
				This will redirect you automatically...
			</p>
		</div>
	)
}

Step 2: Create API Endpoints

Add protected API endpoints in your application that the MCP server can call with authenticated requests.

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 })
	}
}

Step 3: Customize MCP Tools

Replace the example tools in src/index.ts with your own:

// 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)}`,
				},
			],
		}
	}),
)

Configuration Reference

Environment Variables

Variable Description Required
CLERK_SECRET_KEY Your Clerk secret key
CLERK_PUBLISHABLE_KEY Your Clerk publishable key
APP_URL Your application URL

Add your own application-specific environment variables to the Env interface in src/types.ts.

Clerk JWT Templates

Create a JWT template in your Clerk Dashboard for token generation:

  1. Go to JWT Templates in your Clerk Dashboard
  2. Create a new template (e.g., "mcp-server")
  3. Update the template name in src/index.ts:
const token = await getToken(
	// ... token manager
	(this as any).env.CLERK_SECRET_KEY,
	'your-template-name', // Update this
)

Development

Available Scripts

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 + lint

Testing with MCP Inspector

  1. Start the development server: npm run dev
  2. Open MCP Inspector
  3. Set transport type to SSE
  4. Connect to http://localhost:8788/sse
  5. Complete the authentication flow
  6. Test your tools

Deployment

1. Set Production Secrets

wrangler secret put CLERK_SECRET_KEY
wrangler secret put CLERK_PUBLISHABLE_KEY
wrangler secret put APP_URL

2. Create Production KV Namespace

wrangler kv:namespace create "OAUTH_KV" --env production

Update the production KV namespace ID in wrangler.jsonc.

3. Deploy and Configure

npm run deploy

Add your deployed server to Claude Desktop MCP configuration:

{
	"mcpServers": {
		"my-app": {
			"command": "npx",
			"args": [
				"@modelcontextprotocol/server-remote",
				"https://your-mcp-server.your-subdomain.workers.dev/sse"
			]
		}
	}
}

Project Structure

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

Security Considerations

  • OAuth 2.0 ensures secure authentication flow
  • HMAC signatures protect state parameters from tampering
  • Automatic token refresh handles session expiration
  • Session cleanup removes expired OAuth sessions
  • Secure headers include proper CORS and authentication headers

Troubleshooting

Common Issues

Authentication fails:

  • Verify Clerk API keys are correct
  • Ensure your authentication route is implemented
  • Check that JWT template exists in Clerk Dashboard

KV namespace errors:

  • Verify namespace ID in wrangler.jsonc
  • Ensure namespace is created and bound

Tools not working:

  • Check that user is authenticated
  • Verify API endpoints are correct
  • Review Cloudflare Workers logs

Debugging

# View real-time logs
wrangler tail

# Check deployment status
wrangler deployments list

# Test locally with debugging
npm run dev

Contributing

  1. Fork this repository
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Commit your changes: git commit -m 'Add amazing feature'
  4. Push to the branch: git push origin feature/amazing-feature
  5. Open a Pull Request

Resources

License

MIT License - see LICENSE file for details.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选