diff --git a/package-lock.json b/package-lock.json index 307137c506..94f19f2123 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22333,9 +22333,9 @@ } }, "node_modules/@modelcontextprotocol/sdk": { - "version": "1.13.3", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.13.3.tgz", - "integrity": "sha512-bGwA78F/U5G2jrnsdRkPY3IwIwZeWUEfb5o764b79lb0rJmMT76TLwKhdNZOWakOQtedYefwIR4emisEMvInKA==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.16.0.tgz", + "integrity": "sha512-8ofX7gkZcLj9H9rSd50mCgm3SSF8C7XoclxJuLoV0Cz3rEQ1tv9MZRYYvJtm9n1BiEQQMzSmE/w2AEkNacLYfg==", "license": "MIT", "peer": true, "dependencies": { @@ -48619,7 +48619,7 @@ "@langchain/core": "^0.3.62", "@librechat/agents": "^2.4.67", "@librechat/data-schemas": "*", - "@modelcontextprotocol/sdk": "^1.13.3", + "@modelcontextprotocol/sdk": "^1.16.0", "axios": "^1.8.2", "diff": "^7.0.0", "eventsource": "^3.0.2", diff --git a/packages/api/package.json b/packages/api/package.json index f307634b45..ca561a3f85 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -72,7 +72,7 @@ "@langchain/core": "^0.3.62", "@librechat/agents": "^2.4.67", "@librechat/data-schemas": "*", - "@modelcontextprotocol/sdk": "^1.13.3", + "@modelcontextprotocol/sdk": "^1.16.0", "axios": "^1.8.2", "diff": "^7.0.0", "eventsource": "^3.0.2", diff --git a/packages/api/src/mcp/oauth/handler.ts b/packages/api/src/mcp/oauth/handler.ts index ab9bbe46c1..adf1e24372 100644 --- a/packages/api/src/mcp/oauth/handler.ts +++ b/packages/api/src/mcp/oauth/handler.ts @@ -268,6 +268,19 @@ export class MCPOAuthHandler { /** Add state parameter with flowId to the authorization URL */ authorizationUrl.searchParams.set('state', flowId); logger.debug(`[MCPOAuth] Added state parameter to authorization URL`); + + if (resourceMetadata?.resource) { + authorizationUrl.searchParams.set('resource', resourceMetadata.resource); + } else { + logger.warn( + `[MCPOAuth] Resource metadata missing 'resource' property for ${serverName}. ` + + 'This can cause issues with some Authorization Servers who expect a "resource" parameter.', + ); + } + + logger.debug( + `[MCPOAuth] Added resource parameter to authorization URL: ${resourceMetadata.resource}`, + ); } catch (error) { logger.error(`[MCPOAuth] startAuthorization failed:`, error); throw error; @@ -330,12 +343,27 @@ export class MCPOAuthHandler { throw new Error('Invalid flow metadata'); } + let resource; + try { + if (metadata.resourceMetadata?.resource) { + resource = new URL(metadata.resourceMetadata.resource); + logger.debug(`[MCPOAuth] Resource URL for flow ${flowId}: ${resource.toString()}`); + } + } catch (error) { + logger.warn( + `[MCPOAuth] Invalid resource URL format for flow ${flowId}: '${metadata.resourceMetadata!.resource}'. ` + + `Error: ${error instanceof Error ? error.message : 'Unknown error'}. Proceeding without resource parameter.`, + ); + resource = undefined; + } + const tokens = await exchangeAuthorization(metadata.serverUrl, { metadata: metadata.metadata as unknown as SDKOAuthMetadata, clientInformation: metadata.clientInfo, authorizationCode, codeVerifier: metadata.codeVerifier, redirectUri: metadata.clientInfo.redirect_uris?.[0] || this.getDefaultRedirectUri(), + resource: resource, }); logger.debug('[MCPOAuth] Raw tokens from exchange:', {