How do I make an MCP server with auth in Next.js?
How can I make an MCP server? I want to have AUTH and I am using nextjs
I'll help you understand how to create an MCP server with authentication using Next.js. Let me first explore the repository to see what resources and examples are available.
Great! I can see there are excellent examples in the repository. Let me look at the relevant documentation and examples for building an MCP server with Next.js and authentication.
Let me explore the structure of these directories:
Now let me look at the actual code for these examples:
Let me look at the actual MCP route files and configuration:
Now let me look at the xmcp.config.ts and the better-auth setup:
Perfect! Now let me look at the Next.js adapter documentation:
Perfect! Now let me check the documentation for the Next.js adapter:
Perfect! Now let me also check the Better Auth integration documentation:
Excellent! Now I have all the information I need. Let me create a comprehensive response for the user.
##How to Create an MCP Server with AUTH in Next.js
Great question! The xmcp framework makes it easy to add authentication to your MCP server when using Next.js. I'll show you three different approaches based on what the repository offers:
###Option 1: Custom Bearer Token Authentication (Simplest)
This is the built-in withAuth wrapper from xmcp:
import { xmcpHandler, withAuth, VerifyToken } from "@xmcp/adapter";
/**
* Verify the bearer token and return auth information
* In a real implementation, this would validate against your auth service
*/
const verifyToken: VerifyToken = async (req: Request, bearerToken?: string) => {
if (!bearerToken) return undefined;
// Validate token against your database, JWT service, etc.
const isValid = await validateTokenWithYourService(bearerToken);
if (!isValid) return undefined;
return {
token: bearerToken,
scopes: ["read:messages", "write:messages"],
clientId: "example-client",
extra: {
userId: "user-123",
permissions: ["user"],
timestamp: new Date().toISOString(),
},
};
};
const options = {
verifyToken,
required: true, // Make auth mandatory
requiredScopes: ["read:messages"], // Require specific scopes
};
const handler = withAuth(xmcpHandler, options);
export { handler as GET, handler as POST };
Key Features:
- OAuth 2.0 Bearer token support
- Scope validation
- Token expiration checking
- RFC 9728 OAuth Protected Resource Metadata
###Option 2: Better Auth Integration (Recommended for Full Auth)
This is the most comprehensive solution with email/password and OAuth support:
1. Install dependencies:
npm install better-auth pg
npm install -D @types/pg
2. Set up your auth configuration (src/lib/auth.ts):
import { betterAuth } from "better-auth";
import { mcp } from "better-auth/plugins";
import { Pool } from "pg";
export const auth = betterAuth({
database: new Pool({
connectionString: process.env.DATABASE_URL,
}),
baseURL: "http://localhost:3000",
plugins: [
mcp({
loginPage: "/login",
}),
],
emailAndPassword: {
enabled: true,
},
});
3. Create your MCP route (app/mcp/route.ts):
import { xmcpHandler } from "@xmcp/adapter";
import { withMcpAuth } from "better-auth/plugins";
import { auth } from "@/lib/auth";
const handler = withMcpAuth(auth, (req) => {
return xmcpHandler(req);
});
export { handler as GET, handler as POST };
4. Set up environment variables:
DATABASE_URL=postgresql://username:password@localhost:5432/your_database
See the full example: examples/better-auth-nextjs in the repository
###Option 3: API Key Authentication (Simple & Lightweight)
For simpler use cases without OAuth:
import { apiKeyAuthMiddleware, type Middleware } from "xmcp";
const middleware: Middleware = [
apiKeyAuthMiddleware({
headerName: "x-api-key",
validateApiKey: async (apiKey) => {
return apiKey === process.env.MCP_API_KEY;
},
}),
];
export default middleware;
Then connect with the API key in headers:
{
"mcpServers": {
"my-project": {
"url": "http://localhost:3001/mcp",
"headers": {
"x-api-key": "your-api-key"
}
}
}
}
###Setup Steps for Next.js
- Initialize xmcp in your Next.js project:
npx init-xmcp@latest
- Update your
xmcp.config.ts:
import { XmcpConfig } from "xmcp";
const config: XmcpConfig = {
http: true,
experimental: {
adapter: "nextjs",
},
};
export default config;
- Update your
tsconfig.json:
{
"compilerOptions": {
"paths": {
"@xmcp/*": ["./.xmcp/*"]
}
}
}
- Update your package.json scripts:
{
"scripts": {
"dev": "xmcp dev & next dev",
"build": "xmcp build && next build"
}
}
###Which Option to Choose?
| Option | Best For | Complexity |
|---|---|---|
| Bearer Token (Option 1) | Custom auth logic, existing auth services | Low |
| Better Auth (Option 2) | Full auth system with email/OAuth/sessions | Medium-High |
| API Key (Option 3) | Simple access control, internal tools | Very Low |
Check out the working examples in the repo:
examples/auth-nextjs- Bearer token authexamples/better-auth-nextjs- Full Better Auth setupexamples/with-nextjs- Basic Next.js setup without auth
All three patterns use OAuth 2.0 RFC 9728 Protected Resource Metadata, which MCP clients understand natively!
END OF POST
Claude Haiku 4.5