MCP

OAuth MCP

MCP 插件允许您的应用程序作为 MCP 客户端的 OAuth 提供者。它处理身份验证,并简化了为 MCP 应用程序颁发和管理访问令牌的过程。

安装

添加插件

将 MCP 插件添加到您的身份验证配置中,并指定登录页面路径。

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

export const auth = betterAuth({
    plugins: [
        mcp({
            loginPage: "/sign-in" // 您的登录页面路径
        })
    ]
});

此插件没有客户端插件,因此您无需对 authClient 进行任何更改。

生成数据库模式 (Schema)

运行迁移或生成模式,以向数据库添加必要的字段和表。

npx @better-auth/cli migrate
npx @better-auth/cli generate

MCP 插件使用与 OIDC Provider 插件相同的数据库模式。详情请参阅 OIDC Provider 模式 部分。

使用方法

OAuth 发现元数据 (Discovery Metadata)

添加一个路由来为 MCP 客户端公开 OAuth 元数据:

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

export const GET = oAuthDiscoveryMetadata(auth);

MCP 会话处理

您可以使用辅助函数 withMcpAuth 自动获取会话并处理未认证的调用。

api/[transport]/route.ts
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 包含带有作用域和用户 ID 的访问令牌记录
    return createMcpHandler(
        (server) => {
            server.tool(
                "echo",
                "回显消息",
                { message: z.string() },
                async ({ message }) => {
                    return {
                        content: [{ type: "text", text: `工具回显: ${message}` }],
                    };
                },
            );
        },
        {
            capabilities: {
                tools: {
                    echo: {
                        description: "回显消息",
                    },
                },
            },
        },
        {
            redisUrl: process.env.REDIS_URL,
            basePath: "/api",
            verboseLogs: true,
            maxDuration: 60,
        },
    )(req);
});

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

您也可以使用 auth.api.getMcpSession 通过 MCP 客户端发送的访问令牌来获取会话:

api/[transport]/route.ts
import { auth } from "@/lib/auth";
import { createMcpHandler } from "@vercel/mcp-adapter";
import { z } from "zod";

const handler = async (req: Request) => {
     // session 包含带有作用域和用户 ID 的访问令牌记录
    const session = await auth.api.getMcpSession({
        headers: req.headers
    })
    if(!session){
        // 这很重要,您必须返回 401
        return new Response(null, {
            status: 401
        })
    }
    return createMcpHandler(
        (server) => {
            server.tool(
                "echo",
                "回显消息",
                { message: z.string() },
                async ({ message }) => {
                    return {
                        content: [{ type: "text", text: `工具回显: ${message}` }],
                    };
                },
            );
        },
        {
            capabilities: {
                tools: {
                    echo: {
                        description: "回显消息",
                    },
                },
            },
        },
        {
            redisUrl: process.env.REDIS_URL,
            basePath: "/api",
            verboseLogs: true,
            maxDuration: 60,
        },
    )(req);
}

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

配置

MCP 插件接受以下配置选项:

PropTypeDefault
loginPage
string
-
oidcConfig?
object
-

OIDC 配置

该插件通过 oidcConfig 参数支持额外的 OIDC 配置选项:

PropTypeDefault
codeExpiresIn?
number
600
accessTokenExpiresIn?
number
3600
refreshTokenExpiresIn?
number
604800
defaultScope?
string
openid
scopes?
string[]
["openid", "profile", "email", "offline_access"]

模式

MCP 插件使用与 OIDC Provider 插件相同的模式。详情请参阅 OIDC Provider 模式 部分。

On this page