Files
better-auth/examples/nextjs-mcp/README.md
2025-06-23 10:54:16 -07:00

2.1 KiB
Raw Blame History

Better Auth - MCP Demo

This is an example repo on how to setup Better Auth for MCP Auth using Nextjs and Vercel MCP adapter.

Usage

First, add the plugin to your auth instance

// auth.ts
import { betterAuth } from "better-auth";
import { mcp } from "better-auth/plugins";

export const auth = betterAuth({
    plugins: [
        mcp({
            loginPage: "/sign-in" // path to a page where users login
        })
    ]
})

Make sure to generate or migrate required schema using the cli:

npx @better-auth/cli generate ## or (migrate)

Add a route to expose oauth metadata

// .well-known/oauth-authroization-server/route.ts
import { oAuthDiscoveryMetadata } from "better-auth/plugins";
import { auth } from "../../../lib/auth";

export const GET = oAuthDiscoveryMetadata(auth);

Mount the handlers if you haven't

// api/auth/[...all]/route.ts
import { auth } from "@/lib/auth";
import { toNextJsHandler } from "better-auth/next-js";

export const { GET, POST } = toNextJsHandler(auth);

You can use the helper function withMcpAuth to get the session and handle unauthenticated calls automatically.

import { auth } from "@/lib/auth";
import { createMcpHandler } from "@vercel/mcp-adapter";
import { withMcpAuth } from "better-auth/plugins";
import { z } from "zod";

const handler = withMcpAuth(auth, (req, session) => {
    //session => This isnt a typical Better Auth session - instead, it returns the access token record along with the scopes and user ID.
	return createMcpHandler(
		(server) => {
			server.tool(
				"echo",
				"Echo a message",
				{ message: z.string() },
				async ({ message }) => {
					return {
						content: [{ type: "text", text: `Tool echo: ${message}` }],
					};
				},
			);
		},
		{
			capabilities: {
				tools: {
					echo: {
						description: "Echo a message",
					},
				},
			},
		},
		{
			redisUrl: process.env.REDIS_URL,
			basePath: "/api",
			verboseLogs: true,
			maxDuration: 60,
		},
	)(req);
});

export { handler as GET, handler as POST, handler as DELETE };

And that's it!!