oAuthProtectedResourceMetadata is not exported from plugins #1846

Closed
opened 2026-03-13 09:07:52 -05:00 by GiteaMirror · 1 comment
Owner

Originally created by @paoloricciuti on GitHub (Sep 4, 2025).

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

The documentation here states that you need to expose a route to send the oAuthProtectedResourceMetadata which makes sense but:

  1. the route file is wrong (name of the file is .well-known/oauth-authorization-server/route.ts which is to expose the oauth autorization server rather than the metadata
  2. the utility is not actually exported from better-auth/plugins

Am i doing something wrong?

https://www.better-auth.com/docs/plugins/mcp#oauth-protected-resource-metadata

Step to Reproduce

  1. try to import oAuthProtectedResourceMetadata
  2. notice Typescript is mad at you
  3. try to run the code anyway
  4. notice it fails at runtime because it's not exported

Current vs. Expected behavior

oAuthProtectedResourceMetadata is not exported (or even implemented), instead it should

What version of Better Auth are you using?

1.3.7

System info

System:
    OS: macOS 15.6.1
    CPU: (10) arm64 Apple M2 Pro
    Memory: 115.78 MB / 32.00 GB
    Shell: 5.2.32 - /opt/homebrew/bin/bash
  Browsers:
    Chrome: 139.0.7258.155
    Safari: 18.6

Which area(s) are affected? (Select all that apply)

Types, Backend, Documentation, Package

Auth config (if applicable)

import { betterAuth } from 'better-auth';
import { drizzleAdapter } from 'better-auth/adapters/drizzle';
import { db } from '../db/index.ts'; // your drizzle instance
import { createAuthMiddleware, username, mcp } from 'better-auth/plugins';

export const auth = betterAuth({
	emailAndPassword: {
		enabled: true,
	},
	baseURL: 'http://localhost:3000',
	plugins: [
		username(),
		mcp({
			loginPage: '/',
		}),
	],
	database: drizzleAdapter(db, {
		provider: 'sqlite',
	}),
	session: {
		cookieCache: {
			enabled: true,
			maxAge: 5 * 60 * 1000, // 5 minutes
		},
	},
	hooks: {
		after: createAuthMiddleware(async (ctx) => {
			if (
				ctx.path === '/sign-in/email' ||
				ctx.path === '/sign-up/email'
			) {
				if (ctx.context.newSession != null) {
					throw ctx.redirect('/dashboard');
				}
				throw ctx.redirect('/?error=invalid_credentials');
			} else if (ctx.path === '/sign-out') {
				throw ctx.redirect('/');
			}
		}),
	},
});

Additional context

No response

Originally created by @paoloricciuti on GitHub (Sep 4, 2025). ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce The documentation here states that you need to expose a route to send the `oAuthProtectedResourceMetadata` which makes sense but: 1. the route file is wrong (name of the file is `.well-known/oauth-authorization-server/route.ts` which is to expose the oauth autorization server rather than the metadata 2. the utility is not actually exported from `better-auth/plugins` Am i doing something wrong? https://www.better-auth.com/docs/plugins/mcp#oauth-protected-resource-metadata Step to Reproduce 1. try to import `oAuthProtectedResourceMetadata` 2. notice Typescript is mad at you 3. try to run the code anyway 4. notice it fails at runtime because it's not exported ### Current vs. Expected behavior `oAuthProtectedResourceMetadata` is not exported (or even implemented), instead it should ### What version of Better Auth are you using? 1.3.7 ### System info ```bash System: OS: macOS 15.6.1 CPU: (10) arm64 Apple M2 Pro Memory: 115.78 MB / 32.00 GB Shell: 5.2.32 - /opt/homebrew/bin/bash Browsers: Chrome: 139.0.7258.155 Safari: 18.6 ``` ### Which area(s) are affected? (Select all that apply) Types, Backend, Documentation, Package ### Auth config (if applicable) ```typescript import { betterAuth } from 'better-auth'; import { drizzleAdapter } from 'better-auth/adapters/drizzle'; import { db } from '../db/index.ts'; // your drizzle instance import { createAuthMiddleware, username, mcp } from 'better-auth/plugins'; export const auth = betterAuth({ emailAndPassword: { enabled: true, }, baseURL: 'http://localhost:3000', plugins: [ username(), mcp({ loginPage: '/', }), ], database: drizzleAdapter(db, { provider: 'sqlite', }), session: { cookieCache: { enabled: true, maxAge: 5 * 60 * 1000, // 5 minutes }, }, hooks: { after: createAuthMiddleware(async (ctx) => { if ( ctx.path === '/sign-in/email' || ctx.path === '/sign-up/email' ) { if (ctx.context.newSession != null) { throw ctx.redirect('/dashboard'); } throw ctx.redirect('/?error=invalid_credentials'); } else if (ctx.path === '/sign-out') { throw ctx.redirect('/'); } }), }, }); ``` ### Additional context _No response_
GiteaMirror added the plugin label 2026-03-13 09:07:52 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Sep 4, 2025):

Hi @paoloricciuti! I'm Dosu and I’m helping the better-auth team.

You're not doing anything wrong—this was a real gap in Better Auth 1.3.7. The oAuthProtectedResourceMetadata utility wasn't exported from better-auth/plugins, so TypeScript errors and runtime failures are expected if you try to import it as described in the docs. The documentation also pointed to the wrong route file; the correct endpoint for OAuth protected resource metadata is /.well-known/oauth-protected-resource, not /.well-known/oauth-authorization-server PR #4394.

This has just been fixed: as of 2025-09-04, new releases implement and export oAuthProtectedResourceMetadata from the MCP plugin, update the docs, and expose the correct route. There's also a new resource option in the MCP plugin to customize the resource value in the metadata endpoint, defaulting to the base URL origin PR #4419.

If you need this feature, you'll need to upgrade to a version that includes these changes. If you can't upgrade right now, you'll have to implement the endpoint yourself as a workaround. If you relied on the old behavior (full baseURL as the resource), set the resource option explicitly to keep compatibility.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Chat with Dosu Join Discord Share on X

@dosubot[bot] commented on GitHub (Sep 4, 2025): <!-- Greeting --> Hi @paoloricciuti! I'm [Dosu](https://go.dosu.dev/dosubot) and I’m helping the better-auth team. <!-- Answer --> You're not doing anything wrong—this was a real gap in Better Auth 1.3.7. The `oAuthProtectedResourceMetadata` utility wasn't exported from `better-auth/plugins`, so TypeScript errors and runtime failures are expected if you try to import it as described in the docs. The documentation also pointed to the wrong route file; the correct endpoint for OAuth protected resource metadata is `/.well-known/oauth-protected-resource`, not `/.well-known/oauth-authorization-server` [PR #4394](https://github.com/better-auth/better-auth/pull/4394). This has just been fixed: as of 2025-09-04, new releases implement and export `oAuthProtectedResourceMetadata` from the MCP plugin, update the docs, and expose the correct route. There's also a new `resource` option in the MCP plugin to customize the resource value in the metadata endpoint, defaulting to the base URL origin [PR #4419](https://github.com/better-auth/better-auth/pull/4419). If you need this feature, you'll need to upgrade to a version that includes these changes. If you can't upgrade right now, you'll have to implement the endpoint yourself as a workaround. If you relied on the old behavior (full baseURL as the resource), set the `resource` option explicitly to keep compatibility. <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/1569c5a3-5d3b-4569-b986-02ffe4d1b01c?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/1569c5a3-5d3b-4569-b986-02ffe4d1b01c?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/1569c5a3-5d3b-4569-b986-02ffe4d1b01c?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/1569c5a3-5d3b-4569-b986-02ffe4d1b01c?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/1569c5a3-5d3b-4569-b986-02ffe4d1b01c?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/1569c5a3-5d3b-4569-b986-02ffe4d1b01c?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/1569c5a3-5d3b-4569-b986-02ffe4d1b01c?feedback_type=other)</sup>&nbsp;&nbsp;[![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/cdda13d9-dd27-4d31-b09a-5d8bec92de21/ask?utm_source=github)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/better-auth/better-auth/issues/4438)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#1846