diff --git a/.changeset/respect-capability-negotiation.md b/.changeset/respect-capability-negotiation.md index a40ac4e7a..6a42cf607 100644 --- a/.changeset/respect-capability-negotiation.md +++ b/.changeset/respect-capability-negotiation.md @@ -5,6 +5,7 @@ Respect capability negotiation in list methods by returning empty lists when server lacks capability The Client now returns empty lists instead of sending requests to servers that don't advertise the corresponding capability: + - `listPrompts()` returns `{ prompts: [] }` if server lacks prompts capability - `listResources()` returns `{ resources: [] }` if server lacks resources capability - `listResourceTemplates()` returns `{ resourceTemplates: [] }` if server lacks resources capability diff --git a/examples/server/package.json b/examples/server/package.json index 32ee5e2a9..f86cc1375 100644 --- a/examples/server/package.json +++ b/examples/server/package.json @@ -40,7 +40,7 @@ "@modelcontextprotocol/server": "workspace:^", "@modelcontextprotocol/express": "workspace:^", "@modelcontextprotocol/hono": "workspace:^", - "better-auth": "^1.4.7", + "better-auth": "^1.4.17", "cors": "catalog:runtimeServerOnly", "express": "catalog:runtimeServerOnly", "hono": "catalog:runtimeServerOnly", diff --git a/examples/server/src/elicitationUrlExample.ts b/examples/server/src/elicitationUrlExample.ts index e72845f1a..2cc6695c7 100644 --- a/examples/server/src/elicitationUrlExample.ts +++ b/examples/server/src/elicitationUrlExample.ts @@ -239,7 +239,8 @@ setupAuthServer({ authServerUrl, mcpServerUrl, strictResource: true, demoMode: t // Add protected resource metadata route to the MCP server // This allows clients to discover the auth server -app.use(createProtectedResourceMetadataRouter()); +// Pass the resource path so metadata is served at /.well-known/oauth-protected-resource/mcp +app.use(createProtectedResourceMetadataRouter('/mcp')); authMiddleware = requireBearerAuth({ requiredScopes: [], @@ -709,6 +710,7 @@ app.listen(MCP_PORT, error => { process.exit(1); } console.log(`MCP Streamable HTTP Server listening on port ${MCP_PORT}`); + console.log(` Protected Resource Metadata: http://localhost:${MCP_PORT}/.well-known/oauth-protected-resource/mcp`); }); // Handle server shutdown diff --git a/examples/server/src/simpleStreamableHttp.ts b/examples/server/src/simpleStreamableHttp.ts index 75308beff..e016c217f 100644 --- a/examples/server/src/simpleStreamableHttp.ts +++ b/examples/server/src/simpleStreamableHttp.ts @@ -22,6 +22,7 @@ import { isInitializeRequest, McpServer } from '@modelcontextprotocol/server'; +import cors from 'cors'; import type { Request, Response } from 'express'; import * as z from 'zod/v4'; @@ -30,6 +31,7 @@ import { InMemoryEventStore } from './inMemoryEventStore.js'; // Check for OAuth flag const useOAuth = process.argv.includes('--oauth'); const strictOAuth = process.argv.includes('--oauth-strict'); +const dangerousLoggingEnabled = process.argv.includes('--dangerous-logging-enabled'); // Create shared task store for demonstration const taskStore = new InMemoryTaskStore(); @@ -524,6 +526,16 @@ const AUTH_PORT = process.env.MCP_AUTH_PORT ? Number.parseInt(process.env.MCP_AU const app = createMcpExpressApp(); +// Enable CORS for browser-based clients (demo only) +// This allows cross-origin requests and exposes WWW-Authenticate header for OAuth +// WARNING: This configuration is for demo purposes only. In production, you should restrict this to specific origins and configure CORS yourself. +app.use( + cors({ + exposedHeaders: ['WWW-Authenticate', 'Mcp-Session-Id', 'Last-Event-Id', 'Mcp-Protocol-Version'], + origin: '*' // WARNING: This allows all origins to access the MCP server. In production, you should restrict this to specific origins. + }) +); + // Set up OAuth if enabled let authMiddleware = null; if (useOAuth) { @@ -531,11 +543,12 @@ if (useOAuth) { const mcpServerUrl = new URL(`http://localhost:${MCP_PORT}/mcp`); const authServerUrl = new URL(`http://localhost:${AUTH_PORT}`); - setupAuthServer({ authServerUrl, mcpServerUrl, strictResource: strictOAuth, demoMode: true }); + setupAuthServer({ authServerUrl, mcpServerUrl, strictResource: strictOAuth, demoMode: true, dangerousLoggingEnabled }); // Add protected resource metadata route to the MCP server // This allows clients to discover the auth server - app.use(createProtectedResourceMetadataRouter()); + // Pass the resource path so metadata is served at /.well-known/oauth-protected-resource/mcp + app.use(createProtectedResourceMetadataRouter('/mcp')); authMiddleware = requireBearerAuth({ requiredScopes: [], @@ -699,6 +712,9 @@ app.listen(MCP_PORT, error => { process.exit(1); } console.log(`MCP Streamable HTTP Server listening on port ${MCP_PORT}`); + if (useOAuth) { + console.log(` Protected Resource Metadata: http://localhost:${MCP_PORT}/.well-known/oauth-protected-resource/mcp`); + } }); // Handle server shutdown diff --git a/examples/shared/package.json b/examples/shared/package.json index 3d3e7410a..d8758d566 100644 --- a/examples/shared/package.json +++ b/examples/shared/package.json @@ -37,8 +37,9 @@ "@modelcontextprotocol/core": "workspace:^", "@modelcontextprotocol/server": "workspace:^", "@modelcontextprotocol/express": "workspace:^", - "better-auth": "1.4.7", - "better-sqlite3": "^12.4.1", + "better-auth": "^1.4.17", + "better-sqlite3": "^12.6.2", + "cors": "catalog:runtimeServerOnly", "express": "catalog:runtimeServerOnly" }, "devDependencies": { @@ -48,6 +49,7 @@ "@modelcontextprotocol/tsconfig": "workspace:^", "@modelcontextprotocol/vitest-config": "workspace:^", "@types/better-sqlite3": "^7.6.13", + "@types/cors": "catalog:devTools", "@types/express": "catalog:devTools", "@typescript/native-preview": "catalog:devTools", "eslint": "catalog:devTools", diff --git a/examples/shared/src/authMiddleware.ts b/examples/shared/src/authMiddleware.ts index 023df2ce1..8683a7e24 100644 --- a/examples/shared/src/authMiddleware.ts +++ b/examples/shared/src/authMiddleware.ts @@ -26,16 +26,26 @@ export function requireBearerAuth( ): (req: Request, res: Response, next: NextFunction) => Promise { const { requiredScopes = [], resourceMetadataUrl, strictResource = false, expectedResource } = options; + // Build WWW-Authenticate header matching v1.x format + const buildWwwAuthHeader = (errorCode: string, message: string): string => { + let header = `Bearer error="${errorCode}", error_description="${message}"`; + if (requiredScopes.length > 0) { + header += `, scope="${requiredScopes.join(' ')}"`; + } + if (resourceMetadataUrl) { + header += `, resource_metadata="${resourceMetadataUrl.toString()}"`; + } + return header; + }; + return async (req: Request, res: Response, next: NextFunction): Promise => { const authHeader = req.headers.authorization; if (!authHeader || !authHeader.startsWith('Bearer ')) { - const wwwAuthenticate = resourceMetadataUrl ? `Bearer resource_metadata="${resourceMetadataUrl.toString()}"` : 'Bearer'; - - res.set('WWW-Authenticate', wwwAuthenticate); + res.set('WWW-Authenticate', buildWwwAuthHeader('invalid_token', 'Missing Authorization header')); res.status(401).json({ - error: 'unauthorized', - error_description: 'Missing or invalid Authorization header' + error: 'invalid_token', + error_description: 'Missing Authorization header' }); return; } @@ -52,6 +62,7 @@ export function requireBearerAuth( if (requiredScopes.length > 0) { const hasAllScopes = requiredScopes.every(scope => authInfo.scopes.includes(scope)); if (!hasAllScopes) { + res.set('WWW-Authenticate', buildWwwAuthHeader('insufficient_scope', `Required scopes: ${requiredScopes.join(', ')}`)); res.status(403).json({ error: 'insufficient_scope', error_description: `Required scopes: ${requiredScopes.join(', ')}` @@ -63,14 +74,11 @@ export function requireBearerAuth( req.app.locals.auth = authInfo; next(); } catch (error) { - const wwwAuthenticate = resourceMetadataUrl - ? `Bearer error="invalid_token", resource_metadata="${resourceMetadataUrl.toString()}"` - : 'Bearer error="invalid_token"'; - - res.set('WWW-Authenticate', wwwAuthenticate); + const message = error instanceof Error ? error.message : 'Invalid token'; + res.set('WWW-Authenticate', buildWwwAuthHeader('invalid_token', message)); res.status(401).json({ error: 'invalid_token', - error_description: error instanceof Error ? error.message : 'Invalid token' + error_description: message }); } }; diff --git a/examples/shared/src/authServer.ts b/examples/shared/src/authServer.ts index 738163442..e967b23d9 100644 --- a/examples/shared/src/authServer.ts +++ b/examples/shared/src/authServer.ts @@ -11,6 +11,7 @@ import { toNodeHandler } from 'better-auth/node'; import { oAuthDiscoveryMetadata, oAuthProtectedResourceMetadata } from 'better-auth/plugins'; +import cors from 'cors'; import type { Request, Response as ExpressResponse, Router } from 'express'; import express from 'express'; @@ -25,6 +26,12 @@ export interface SetupAuthServerOptions { * Examples should be used for **demo** only and not for production purposes, however this mode disables some logging and other features. */ demoMode: boolean; + /** + * Enable verbose logging of better-auth requests/responses. + * WARNING: This may log sensitive information like tokens and cookies. + * Only use for debugging purposes. + */ + dangerousLoggingEnabled?: boolean; } // Store auth instance globally so it can be used for token verification @@ -79,7 +86,7 @@ async function ensureDemoUserExists(auth: DemoAuth): Promise { * @param options - Server configuration */ export function setupAuthServer(options: SetupAuthServerOptions): void { - const { authServerUrl, mcpServerUrl, demoMode } = options; + const { authServerUrl, mcpServerUrl, demoMode, dangerousLoggingEnabled = false } = options; // Create better-auth instance with MCP plugin const auth = createDemoAuth({ @@ -96,54 +103,68 @@ export function setupAuthServer(options: SetupAuthServerOptions): void { const authApp = express(); // Enable CORS for all origins (demo only) - must be before other middleware - authApp.use((_req, res, next) => { - res.header('Access-Control-Allow-Origin', '*'); - res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); - res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization'); - res.header('Access-Control-Expose-Headers', 'WWW-Authenticate'); - if (_req.method === 'OPTIONS') { - res.sendStatus(200); - return; - } - next(); - }); + // WARNING: This configuration is for demo purposes only. In production, you should restrict this to specific origins and configure CORS yourself. + authApp.use( + cors({ + origin: '*' // WARNING: This allows all origins to access the auth server. In production, you should restrict this to specific origins. + }) + ); - // Request logging middleware for OAuth endpoints - authApp.use('/api/auth', (req, res, next) => { - const timestamp = new Date().toISOString(); - console.log(`${timestamp} [Auth Request] ${req.method} ${req.url}`); - if (req.method === 'POST') { - console.log(`${timestamp} [Auth Request] Content-Type: ${req.headers['content-type']}`); - } + // Create better-auth handler + // toNodeHandler bypasses Express methods + const betterAuthHandler = toNodeHandler(auth); - if (demoMode) { - // Log response when it finishes - const originalSend = res.send.bind(res); - res.send = function (body) { - console.log(`${timestamp} [Auth Response] ${res.statusCode} ${req.url}`); - if (res.statusCode >= 400 && body) { - try { - const parsed = typeof body === 'string' ? JSON.parse(body) : body; - console.log(`${timestamp} [Auth Response] Error:`, parsed); - } catch { - // Not JSON, log as-is if short - if (typeof body === 'string' && body.length < 200) { - console.log(`${timestamp} [Auth Response] Body: ${body}`); - } + // Mount better-auth handler BEFORE body parsers + // toNodeHandler reads the raw request body, so Express must not consume it first + if (dangerousLoggingEnabled) { + // Verbose logging mode - intercept at Node.js level to see all requests/responses + // WARNING: This may log sensitive information like tokens and cookies + authApp.all('/api/auth/{*splat}', (req, res) => { + const ts = new Date().toISOString(); + console.log(`\n${'='.repeat(60)}`); + console.log(`${ts} [AUTH] ${req.method} ${req.originalUrl}`); + console.log(`${ts} [AUTH] Query:`, JSON.stringify(req.query)); + console.log(`${ts} [AUTH] Headers.Cookie:`, req.headers.cookie?.slice(0, 100)); + + // Intercept writeHead to capture status and headers (including redirects) + const originalWriteHead = res.writeHead.bind(res); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + res.writeHead = function (statusCode: number, ...args: any[]) { + console.log(`${ts} [AUTH] >>> Response Status: ${statusCode}`); + // Headers can be in different positions depending on the overload + const headers = args.find(a => typeof a === 'object' && a !== null); + if (headers) { + if (headers.location || headers.Location) { + console.log(`${ts} [AUTH] >>> Location (redirect): ${headers.location || headers.Location}`); } + console.log(`${ts} [AUTH] >>> Headers:`, JSON.stringify(headers)); } - return originalSend(body); + return originalWriteHead(statusCode, ...args); }; - } - next(); - }); - // Mount better-auth handler BEFORE body parsers - // toNodeHandler reads the raw request body, so Express must not consume it first - authApp.all('/api/auth/{*splat}', toNodeHandler(auth)); + // Intercept write to capture response body + const originalWrite = res.write.bind(res); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + res.write = function (chunk: any, ...args: any[]) { + if (chunk) { + const bodyPreview = typeof chunk === 'string' ? chunk.slice(0, 500) : chunk.toString().slice(0, 500); + console.log(`${ts} [AUTH] >>> Body: ${bodyPreview}`); + } + // eslint-disable-next-line @typescript-eslint/no-explicit-any + return originalWrite(chunk, ...(args as [any])); + }; + + return betterAuthHandler(req, res); + }); + } else { + // Normal mode - no verbose logging + authApp.all('/api/auth/{*splat}', toNodeHandler(auth)); + } // OAuth metadata endpoints using better-auth's built-in handlers - authApp.get('/.well-known/oauth-authorization-server', toNodeHandler(oAuthDiscoveryMetadata(auth))); + // Add explicit OPTIONS handler for CORS preflight + authApp.options('/.well-known/oauth-authorization-server', cors()); + authApp.get('/.well-known/oauth-authorization-server', cors(), toNodeHandler(oAuthDiscoveryMetadata(auth))); // Body parsers for non-better-auth routes (like /sign-in) authApp.use(express.json()); @@ -239,14 +260,25 @@ export function setupAuthServer(options: SetupAuthServerOptions): void { * This is needed because MCP clients discover the auth server by first * fetching protected resource metadata from the MCP server. * + * Per RFC 9728 Section 3, the metadata URL includes the resource path. + * E.g., for resource http://localhost:3000/mcp, metadata is at + * http://localhost:3000/.well-known/oauth-protected-resource/mcp + * * See: https://www.better-auth.com/docs/plugins/mcp#oauth-protected-resource-metadata + * + * @param resourcePath - The path of the MCP resource (e.g., '/mcp'). Defaults to '/mcp'. */ -export function createProtectedResourceMetadataRouter(): Router { +export function createProtectedResourceMetadataRouter(resourcePath = '/mcp'): Router { const auth = getAuth(); const router = express.Router(); - // Serve at the standard well-known path - router.get('/.well-known/oauth-protected-resource', toNodeHandler(oAuthProtectedResourceMetadata(auth))); + // Construct the metadata path per RFC 9728 Section 3 + const metadataPath = `/.well-known/oauth-protected-resource${resourcePath}`; + + // Enable CORS for browser-based clients to discover the auth server + // Add explicit OPTIONS handler for CORS preflight + router.options(metadataPath, cors()); + router.get(metadataPath, cors(), toNodeHandler(oAuthProtectedResourceMetadata(auth))); return router; } diff --git a/examples/shared/tsconfig.json b/examples/shared/tsconfig.json index 69d2f966a..74c1e1172 100644 --- a/examples/shared/tsconfig.json +++ b/examples/shared/tsconfig.json @@ -3,6 +3,8 @@ "include": ["./"], "exclude": ["node_modules", "dist"], "compilerOptions": { + "declaration": false, + "declarationMap": false, "paths": { "*": ["./*"], "@modelcontextprotocol/server": ["./node_modules/@modelcontextprotocol/server/src/index.ts"], diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7820ada8b..5d71ed359 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -342,8 +342,8 @@ importers: specifier: workspace:^ version: link:../../packages/server better-auth: - specifier: ^1.4.7 - version: 1.4.7(better-sqlite3@12.5.0)(vitest@4.0.16(@types/node@24.10.4)(tsx@4.21.0)(yaml@2.8.2)) + specifier: ^1.4.17 + version: 1.4.17(better-sqlite3@12.6.2)(vitest@4.0.16(@types/node@24.10.4)(tsx@4.21.0)(yaml@2.8.2)) cors: specifier: catalog:runtimeServerOnly version: 2.8.5 @@ -388,11 +388,14 @@ importers: specifier: workspace:^ version: link:../../packages/server better-auth: - specifier: 1.4.7 - version: 1.4.7(better-sqlite3@12.5.0)(vitest@4.0.16(@types/node@24.10.4)(tsx@4.21.0)(yaml@2.8.2)) + specifier: ^1.4.17 + version: 1.4.17(better-sqlite3@12.6.2)(vitest@4.0.16(@types/node@24.10.4)(tsx@4.21.0)(yaml@2.8.2)) better-sqlite3: - specifier: ^12.4.1 - version: 12.5.0 + specifier: ^12.6.2 + version: 12.6.2 + cors: + specifier: catalog:runtimeServerOnly + version: 2.8.5 express: specifier: catalog:runtimeServerOnly version: 5.2.1 @@ -415,6 +418,9 @@ importers: '@types/better-sqlite3': specifier: ^7.6.13 version: 7.6.13 + '@types/cors': + specifier: catalog:devTools + version: 2.8.19 '@types/express': specifier: catalog:devTools version: 5.0.6 @@ -932,20 +938,20 @@ packages: resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} engines: {node: '>=6.9.0'} - '@better-auth/core@1.4.7': - resolution: {integrity: sha512-rNfj8aNFwPwAMYo+ahoWDsqKrV7svD3jhHSC6+A77xxKodbgV0UgH+RO21GMaZ0PPAibEl851nw5e3bsNslW/w==} + '@better-auth/core@1.4.17': + resolution: {integrity: sha512-WSaEQDdUO6B1CzAmissN6j0lx9fM9lcslEYzlApB5UzFaBeAOHNUONTdglSyUs6/idiZBoRvt0t/qMXCgIU8ug==} peerDependencies: '@better-auth/utils': 0.3.0 '@better-fetch/fetch': 1.1.21 - better-call: 1.1.5 + better-call: 1.1.8 jose: ^6.1.0 kysely: ^0.28.5 nanostores: ^1.0.1 - '@better-auth/telemetry@1.4.7': - resolution: {integrity: sha512-k07C/FWnX6m+IxLruNkCweIxuaIwVTB2X40EqwamRVhYNBAhOYZFGLHH+PtQyM+Yf1Z4+8H6MugLOXSreXNAjQ==} + '@better-auth/telemetry@1.4.17': + resolution: {integrity: sha512-R1BC4e/bNjQbXu7lG6ubpgmsPj7IMqky5DvMlzAtnAJWJhh99pMh/n6w5gOHa0cqDZgEAuj75IPTxv+q3YiInA==} peerDependencies: - '@better-auth/core': 1.4.7 + '@better-auth/core': 1.4.17 '@better-auth/utils@0.3.0': resolution: {integrity: sha512-W+Adw6ZA6mgvnSnhOki270rwJ42t4XzSK6YWGF//BbVXL6SwCLWfyzBc1lN2m/4RM28KubdBKQ4X5VMoLRNPQw==} @@ -2083,26 +2089,27 @@ packages: resolution: {integrity: sha512-B0xUquLkiGLgHhpPBqvl7GWegWBUNuujQ6kXd/r1U38ElPT6Ok8KZ8e+FpUGEc2ZoRQUzq/aUnaKFc/svWUGSg==} hasBin: true - better-auth@1.4.7: - resolution: {integrity: sha512-kVmDQxzqGwP4FFMOYpS5I7oAaoFW3hwooUAAtcbb2DrOYv5EUvRUDJbTMaPoMTj7URjNDQ6vG9gcCS1Q+0aVBw==} + better-auth@1.4.17: + resolution: {integrity: sha512-VmHGQyKsEahkEs37qguROKg/6ypYpNF13D7v/lkbO7w7Aivz0Bv2h+VyUkH4NzrGY0QBKXi1577mGhDCVwp0ew==} peerDependencies: '@lynx-js/react': '*' - '@prisma/client': ^5.22.0 + '@prisma/client': ^5.0.0 || ^6.0.0 || ^7.0.0 '@sveltejs/kit': ^2.0.0 '@tanstack/react-start': ^1.0.0 - better-sqlite3: ^12.4.1 - drizzle-kit: ^0.31.4 - drizzle-orm: ^0.41.0 - mongodb: ^6.18.0 - mysql2: ^3.14.4 + '@tanstack/solid-start': ^1.0.0 + better-sqlite3: ^12.0.0 + drizzle-kit: '>=0.31.4' + drizzle-orm: '>=0.41.0' + mongodb: ^6.0.0 || ^7.0.0 + mysql2: ^3.0.0 next: ^14.0.0 || ^15.0.0 || ^16.0.0 - pg: ^8.16.3 - prisma: ^5.22.0 + pg: ^8.0.0 + prisma: ^5.0.0 || ^6.0.0 || ^7.0.0 react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 solid-js: ^1.0.0 svelte: ^4.0.0 || ^5.0.0 - vitest: ^4.0.15 + vitest: ^2.0.0 || ^3.0.0 || ^4.0.0 vue: ^3.0.0 peerDependenciesMeta: '@lynx-js/react': @@ -2113,6 +2120,8 @@ packages: optional: true '@tanstack/react-start': optional: true + '@tanstack/solid-start': + optional: true better-sqlite3: optional: true drizzle-kit: @@ -2142,8 +2151,8 @@ packages: vue: optional: true - better-call@1.1.5: - resolution: {integrity: sha512-nQJ3S87v6wApbDwbZ++FrQiSiVxWvZdjaO+2v6lZJAG2WWggkB2CziUDjPciz3eAt9TqfRursIQMZIcpkBnvlw==} + better-call@1.1.8: + resolution: {integrity: sha512-XMQ2rs6FNXasGNfMjzbyroSwKwYbZ/T3IxruSS6U2MJRsSYh3wYtG3o6H00ZlKZ/C/UPOAD97tqgQJNsxyeTXw==} peerDependencies: zod: ^4.0.0 peerDependenciesMeta: @@ -2154,8 +2163,8 @@ packages: resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} engines: {node: '>=4'} - better-sqlite3@12.5.0: - resolution: {integrity: sha512-WwCZ/5Diz7rsF29o27o0Gcc1Du+l7Zsv7SYtVPG0X3G/uUI1LqdxrQI7c9Hs2FWpqXXERjW9hp6g3/tH7DlVKg==} + better-sqlite3@12.6.2: + resolution: {integrity: sha512-8VYKM3MjCa9WcaSAI3hzwhmyHVlH8tiGFwf0RlTsZPWJ1I5MkzjiudCo4KC4DxOaL/53A5B1sI/IbldNFDbsKA==} engines: {node: 20.x || 22.x || 23.x || 24.x || 25.x} bindings@1.5.0: @@ -4069,20 +4078,20 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 - '@better-auth/core@1.4.7(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.5(zod@4.3.5))(jose@6.1.3)(kysely@0.28.9)(nanostores@1.1.0)': + '@better-auth/core@1.4.17(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.8(zod@4.3.5))(jose@6.1.3)(kysely@0.28.9)(nanostores@1.1.0)': dependencies: '@better-auth/utils': 0.3.0 '@better-fetch/fetch': 1.1.21 '@standard-schema/spec': 1.1.0 - better-call: 1.1.5(zod@4.3.5) + better-call: 1.1.8(zod@4.3.5) jose: 6.1.3 kysely: 0.28.9 nanostores: 1.1.0 zod: 4.3.5 - '@better-auth/telemetry@1.4.7(@better-auth/core@1.4.7(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.5(zod@4.3.5))(jose@6.1.3)(kysely@0.28.9)(nanostores@1.1.0))': + '@better-auth/telemetry@1.4.17(@better-auth/core@1.4.17(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.8(zod@4.3.5))(jose@6.1.3)(kysely@0.28.9)(nanostores@1.1.0))': dependencies: - '@better-auth/core': 1.4.7(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.5(zod@4.3.5))(jose@6.1.3)(kysely@0.28.9)(nanostores@1.1.0) + '@better-auth/core': 1.4.17(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.8(zod@4.3.5))(jose@6.1.3)(kysely@0.28.9)(nanostores@1.1.0) '@better-auth/utils': 0.3.0 '@better-fetch/fetch': 1.1.21 @@ -5160,25 +5169,25 @@ snapshots: baseline-browser-mapping@2.9.14: {} - better-auth@1.4.7(better-sqlite3@12.5.0)(vitest@4.0.16(@types/node@24.10.4)(tsx@4.21.0)(yaml@2.8.2)): + better-auth@1.4.17(better-sqlite3@12.6.2)(vitest@4.0.16(@types/node@24.10.4)(tsx@4.21.0)(yaml@2.8.2)): dependencies: - '@better-auth/core': 1.4.7(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.5(zod@4.3.5))(jose@6.1.3)(kysely@0.28.9)(nanostores@1.1.0) - '@better-auth/telemetry': 1.4.7(@better-auth/core@1.4.7(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.5(zod@4.3.5))(jose@6.1.3)(kysely@0.28.9)(nanostores@1.1.0)) + '@better-auth/core': 1.4.17(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.8(zod@4.3.5))(jose@6.1.3)(kysely@0.28.9)(nanostores@1.1.0) + '@better-auth/telemetry': 1.4.17(@better-auth/core@1.4.17(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.8(zod@4.3.5))(jose@6.1.3)(kysely@0.28.9)(nanostores@1.1.0)) '@better-auth/utils': 0.3.0 '@better-fetch/fetch': 1.1.21 '@noble/ciphers': 2.1.1 '@noble/hashes': 2.0.1 - better-call: 1.1.5(zod@4.3.5) + better-call: 1.1.8(zod@4.3.5) defu: 6.1.4 jose: 6.1.3 kysely: 0.28.9 nanostores: 1.1.0 zod: 4.3.5 optionalDependencies: - better-sqlite3: 12.5.0 + better-sqlite3: 12.6.2 vitest: 4.0.16(@types/node@24.10.4)(tsx@4.21.0)(yaml@2.8.2) - better-call@1.1.5(zod@4.3.5): + better-call@1.1.8(zod@4.3.5): dependencies: '@better-auth/utils': 0.3.0 '@better-fetch/fetch': 1.1.21 @@ -5191,7 +5200,7 @@ snapshots: dependencies: is-windows: 1.0.2 - better-sqlite3@12.5.0: + better-sqlite3@12.6.2: dependencies: bindings: 1.5.0 prebuild-install: 7.1.3 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 4213eb9ff..04288d9f7 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -57,8 +57,8 @@ linkWorkspacePackages: deep minimumReleaseAge: 10080 # 7 days minimumReleaseAgeExclude: - '@modelcontextprotocol/conformance' - - hono@4.11.4 # fixes https://github.com/advisories/GHSA-3vhc-576x-3qv4 https://github.com/advisories/GHSA-f67f-6cw9-8mq4 - - '@hono/node-server@1.19.9' # https://github.com/honojs/node-server/pull/295 + - hono@4.11.4 # fixes https://github.com/advisories/GHSA-3vhc-576x-3qv4 https://github.com/advisories/GHSA-f67f-6cw9-8mq4 + - '@hono/node-server@1.19.9' # https://github.com/honojs/node-server/pull/295 onlyBuiltDependencies: - better-sqlite3