MCP
用于 Better Auth 的 MCP 提供者插件
OAuth MCP
该插件很快将被弃用,转而使用 OAuth 提供者插件。
MCP 插件让你的应用可以作为 MCP 客户端的 OAuth 提供者。它处理认证,并简化了为 MCP 应用颁发和管理访问令牌的流程。
该插件基于 OIDC 提供者插件。将来它会迁移到 OAuth 提供者插件。
安装
添加插件
将 MCP 插件添加到你的认证配置中,并指定登录页面路径。
import { betterAuth } from "better-auth";
import { mcp } from "better-auth/plugins";
export const auth = betterAuth({
plugins: [
mcp({
loginPage: "/sign-in" // 登录页面路径
})
]
});此插件没有客户端插件,因此无需对 authClient 进行任何更改。
生成架构
运行迁移或生成架构,以向数据库添加必要的字段和表。
npx auth migratenpx auth generateMCP 插件使用与 OIDC 提供者插件相同的架构。请参阅 OIDC 提供者架构 部分了解详细信息。
使用
OAuth 发现元数据
Better Auth 已自动处理 /api/auth/.well-known/oauth-authorization-server 路由,但有些客户端可能无法解析 WWW-Authenticate 头,而是默认访问 /.well-known/oauth-authorization-server(例如,当 CORS 配置未暴露 WWW-Authenticate 时)。因此,建议添加路由以公开 MCP 客户端的 OAuth 元数据:
import { oAuthDiscoveryMetadata } from "better-auth/plugins";
import { auth } from "../../../lib/auth";
export const GET = oAuthDiscoveryMetadata(auth);OAuth 受保护资源元数据
Better Auth 同样自动处理 /api/auth/.well-known/oauth-protected-resource 路由,但某些客户端也可能无法解析 WWW-Authenticate 头,而是默认访问 /.well-known/oauth-protected-resource。因此,建议添加路由以公开 MCP 客户端的 OAuth 元数据:
import { oAuthProtectedResourceMetadata } from "better-auth/plugins";
import { auth } from "@/lib/auth";
export const GET = oAuthProtectedResourceMetadata(auth);MCP 会话处理
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",
"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 };你也可以使用 auth.api.getMcpSession 通过 MCP 客户端发送的访问令牌获取会话:
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",
"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 };配置
MCP 插件接受以下配置选项:
Prop
Type
OIDC 配置
通过 oidcConfig 参数,插件支持额外的 OIDC 配置选项:
Prop
Type
Prop
Type
会话对象
verifyToken 返回并传递给处理函数的会话对象包含:
Prop
Type
Schema
MCP 插件使用与 OIDC Provider 插件相同的 Schema。详情请参阅OIDC Provider Schema章节。