MCP Plugin (@better-auth/mcp)#
Overview#
The MCP (Model Context Protocol) plugin enables a Better Auth instance to act as an OAuth 2.1 authorization server for MCP clients . Originally shipped inside better-auth on top of the deprecated oidc-provider plugin, serving OAuth endpoints under /mcp/* , MCP was extracted into its own standalone package as of v1.7.0-beta.6 .
The new @better-auth/mcp is rebuilt on the maintained @better-auth/oauth-provider . The architectural boundary is clear: oauth-provider is the authorization server; MCP is the resource server that serves RFC 9728 protected resource metadata and verifies bearer tokens .
⚠️ The legacy
mcpplugin still exists insidebetter-auth/pluginsbut is deprecated and will be removed. The current docs at better-auth.com/docs/plugins/mcp still reflect the old version .
Import Paths#
| What | Old (deprecated) | New (@better-auth/mcp) |
|---|---|---|
| Server plugin | better-auth/plugins | @better-auth/mcp |
| Auth middleware | better-auth/plugins (withMcpAuth) | @better-auth/mcp (requireMcpAuth) |
| Remote client | better-auth/plugins/mcp/client (createMcpAuthClient) | @better-auth/mcp/client (createMcpResourceClient) |
| Framework adapters | better-auth/plugins/mcp/client/adapters | @better-auth/mcp/client/adapters |
Public API Surface#
Server-side (@better-auth/mcp)#
mcp(options)— main plugin. Configures the OAuth provider for MCP. Key option:resource(RFC 8707 resource identifier URI; defaults to the auth server's base URL) .requireMcpAuth(auth, handler, opts?)— route guard that validates the bearer token against JWKS and forwards verified JWT claims to the handler. Replaces oldwithMcpAuth.mcpHandler(verifyOptions, handler, opts?)— explicit token verifier for resource servers running separately from the auth server .
Token verification in the new package is JWT-claims-based (using JOSE + JWKS discovery), not session-record-based as in the old plugin .
Remote client (@better-auth/mcp/client)#
createMcpResourceClient(options)— framework-agnostic client for resource servers that are separate processes/services. Returns:verifyToken,handler,discoveryHandler,protectedResourceHandler,middleware.
Framework adapters (@better-auth/mcp/client/adapters)#
mcpAuthHono(options)— Hono middleware + discovery routesmcpAuthOfficial(options)— Official MCP SDK (@modelcontextprotocol/sdk) wrappermcpAuthMcpUse(options)— drop-inmcp-useOAuth provider
Breaking Changes from Old Plugin#
| Area | Before | After |
|---|---|---|
| Package | better-auth | @better-auth/mcp (+ @better-auth/oauth-provider) |
| OAuth endpoint prefix | /mcp/* | /oauth2/* |
| Authorization | /mcp/authorize | /oauth2/authorize |
| Token | /mcp/token | /oauth2/token |
| Discovery (auth server) | /api/auth/.well-known/... only | Also /.well-known/oauth-authorization-server (RFC 8414) |
| Discovery (resource) | /api/auth/.well-known/... only | Also /.well-known/oauth-protected-resource (RFC 9728) |
| Session middleware | withMcpAuth | requireMcpAuth |
| Remote client factory | createMcpAuthClient | createMcpResourceClient |
| Config nesting | oidcConfig: { ... } | Flat options on mcp({ ... }) |
| DB table | oauthApplication | oauthClient (+ new oauthRefreshToken, oauthClientAssertion) |
| JWT plugin | Optional | Required (provides signing key + /jwks endpoint) |
After migrating, run npx auth migrate or npx auth generate to apply schema changes .
Legacy Plugin (Still in better-auth/plugins)#
The legacy plugin (pre-extraction) is documented at mcp.mdx and currently live on better-auth.com. Key legacy APIs:
mcp({ loginPage, resource?, oidcConfig? })— imported frombetter-auth/pluginswithMcpAuth(auth, handler)— session-based route guardauth.api.getMcpSession({ headers })— direct session lookupcreateMcpAuthClient({ authURL })— remote client frombetter-auth/plugins/mcp/clientoAuthDiscoveryMetadata(auth),oAuthProtectedResourceMetadata(auth)— helper route exports frombetter-auth/plugins- Framework adapters:
mcpAuthHono,mcpAuthOfficial,mcpAuthMcpUsefrombetter-auth/plugins/mcp/client/adapters
The legacy session object includes accessToken, refreshToken, clientId, userId, scopes, and expiry fields .
Integration Patterns#
Same-process (legacy or new, co-located)#
Use withMcpAuth (legacy) or requireMcpAuth (new) directly with the auth instance when the MCP server and auth server share a process.
Separate resource server#
Use createMcpResourceClient pointed at the auth server's authURL. The client discovers JWKS via RFC 8414 metadata and verifies tokens locally — no database calls required. Mount discoveryHandler() and protectedResourceHandler(resourceUrl) at /.well-known/* paths on the MCP server .
Key Source Files#
| File | Purpose |
|---|---|
legacy mcp/index.ts | Old plugin implementation (OIDC-based, inside better-auth) |
legacy mcp/client/index.ts | Old remote client (createMcpAuthClient) |
legacy mcp/client/adapters.ts | Old framework adapters |
MCP docs (mcp.mdx) | Official plugin documentation (reflects legacy API) |
| PR #9992 | Full extraction changeset and migration notes |