From a07e0e5ab6145f4122bd2ae270ded35fa5efe1f8 Mon Sep 17 00:00:00 2001 From: Thomas Camlong Date: Wed, 19 Aug 2026 10:23:57 +0200 Subject: [PATCH] fix(mcp): derive OAuth login redirect and well-known discovery from request base URL --- apps/nextjs/next.config.ts | 9 +++++++++ apps/nextjs/src/app/api/mcp/oauth/authorize/route.ts | 4 +++- .../oauth-authorization-server/route.ts | 0 .../oauth-protected-resource/route.ts | 0 4 files changed, 12 insertions(+), 1 deletion(-) rename apps/nextjs/src/app/{.well-known => well-known}/oauth-authorization-server/route.ts (100%) rename apps/nextjs/src/app/{.well-known => well-known}/oauth-protected-resource/route.ts (100%) diff --git a/apps/nextjs/next.config.ts b/apps/nextjs/next.config.ts index 2105259be..14b85f561 100644 --- a/apps/nextjs/next.config.ts +++ b/apps/nextjs/next.config.ts @@ -64,6 +64,15 @@ const nextConfig: NextConfig = { }, ], }, + // skipcq: JS-0116 + // eslint-disable-next-line @typescript-eslint/require-await,no-restricted-syntax + async rewrites() { + return [ + { source: "/.well-known/:path*", destination: "/well-known/:path*" }, + { source: "/api/mcp/:transport/.well-known/:path*", destination: "/well-known/:path*" }, + ]; + }, + // skipcq: JS-0116 // eslint-disable-next-line @typescript-eslint/require-await,no-restricted-syntax async headers() { diff --git a/apps/nextjs/src/app/api/mcp/oauth/authorize/route.ts b/apps/nextjs/src/app/api/mcp/oauth/authorize/route.ts index 927cdf60f..dfc171000 100644 --- a/apps/nextjs/src/app/api/mcp/oauth/authorize/route.ts +++ b/apps/nextjs/src/app/api/mcp/oauth/authorize/route.ts @@ -1,5 +1,6 @@ import type { NextRequest } from "next/server"; +import { extractBaseUrlFromHeaders } from "@homarr/common"; import { auth } from "@homarr/auth/next"; import { consumePendingAuth, createAuthCode, getClient, storePendingAuth } from "../_store"; @@ -137,7 +138,8 @@ export async function GET(req: NextRequest) { ); } - const loginUrl = new URL("/auth/login", url.origin); + const baseUrl = extractBaseUrlFromHeaders(req.headers); + const loginUrl = new URL("/auth/login", baseUrl); loginUrl.searchParams.set("callbackUrl", `/api/mcp/oauth/authorize?pending=${id}`); return Response.redirect(loginUrl.toString()); } diff --git a/apps/nextjs/src/app/.well-known/oauth-authorization-server/route.ts b/apps/nextjs/src/app/well-known/oauth-authorization-server/route.ts similarity index 100% rename from apps/nextjs/src/app/.well-known/oauth-authorization-server/route.ts rename to apps/nextjs/src/app/well-known/oauth-authorization-server/route.ts diff --git a/apps/nextjs/src/app/.well-known/oauth-protected-resource/route.ts b/apps/nextjs/src/app/well-known/oauth-protected-resource/route.ts similarity index 100% rename from apps/nextjs/src/app/.well-known/oauth-protected-resource/route.ts rename to apps/nextjs/src/app/well-known/oauth-protected-resource/route.ts