feat: MCP plugin (#2666)

* chore: wip

* wip

* feat: mcp plugin

* wip

* chore: fix lock file

* clean up

* schema

* docs

* chore: lint

* chore: release v1.2.9-beta.1

* blog

* chore: lint
This commit is contained in:
Bereket Engida
2025-05-23 12:44:51 -07:00
committed by GitHub
parent a12b7fc331
commit 9cc2e3d8ab
56 changed files with 4540 additions and 239 deletions

View File

@@ -0,0 +1,4 @@
import { oAuthDiscoveryMetadata } from "better-auth/plugins";
import { auth } from "../../../lib/auth";
export const GET = oAuthDiscoveryMetadata(auth);

View File

@@ -0,0 +1,38 @@
import { createMcpHandler } from "@vercel/mcp-adapter";
import { withMcpAuth } from "better-auth/plugins";
import { z } from "zod";
import { auth } from "@/lib/auth";
const handler = withMcpAuth(auth, (req, session) => {
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 };

View File

@@ -1,10 +1,4 @@
import { auth } from "@/lib/auth";
import { toNextJsHandler } from "better-auth/next-js";
import { NextRequest } from "next/server";
export const { GET } = toNextJsHandler(auth);
export const POST = async (req: NextRequest) => {
const res = await auth.handler(req);
return res;
};
export const { GET, POST } = toNextJsHandler(auth);

View File

@@ -8,8 +8,8 @@ import {
oneTap,
oAuthProxy,
openAPI,
oidcProvider,
customSession,
mcp,
} from "better-auth/plugins";
import { reactInvitationEmail } from "./email/invitation";
import { LibsqlDialect } from "@libsql/kysely-libsql";
@@ -19,9 +19,9 @@ import { MysqlDialect } from "kysely";
import { createPool } from "mysql2/promise";
import { nextCookies } from "better-auth/next-js";
import { passkey } from "better-auth/plugins/passkey";
import { expo } from "@better-auth/expo";
import { stripe } from "@better-auth/stripe";
import { Stripe } from "stripe";
import Database from "better-sqlite3";
const from = process.env.BETTER_AUTH_EMAIL || "delivered@resend.dev";
const to = process.env.TEST_EMAIL || "";
@@ -52,10 +52,7 @@ const STARTER_PRICE_ID = {
export const auth = betterAuth({
appName: "Better Auth Demo",
database: {
dialect,
type: process.env.USE_MYSQL ? "mysql" : "sqlite",
},
database: new Database("auth.db"),
emailVerification: {
async sendVerificationEmail({ user, url }) {
const res = await resend.emails.send({
@@ -117,6 +114,9 @@ export const auth = betterAuth({
},
},
plugins: [
mcp({
loginPage: "/sign-in",
}),
organization({
async sendInvitationEmail(data) {
await resend.emails.send({
@@ -160,9 +160,7 @@ export const auth = betterAuth({
multiSession(),
oAuthProxy(),
nextCookies(),
oidcProvider({
loginPage: "/sign-in",
}),
oneTap(),
customSession(async (session) => {
return {
@@ -198,7 +196,6 @@ export const auth = betterAuth({
],
},
}),
expo(),
],
trustedOrigins: ["exp://"],
});