feat: mcp - support audiences for OAuth2 (#5265)

This commit is contained in:
Mikhail Aksenov 2025-08-06 00:02:16 +02:00 committed by GitHub
parent 29c3825604
commit dadf05809c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 16 additions and 0 deletions

View File

@ -169,6 +169,7 @@ Use the `/mcp auth` command to manage OAuth authentication:
- **`scopes`** (string[]): Required OAuth scopes - **`scopes`** (string[]): Required OAuth scopes
- **`redirectUri`** (string): Custom redirect URI (defaults to `http://localhost:7777/oauth/callback`) - **`redirectUri`** (string): Custom redirect URI (defaults to `http://localhost:7777/oauth/callback`)
- **`tokenParamName`** (string): Query parameter name for tokens in SSE URLs - **`tokenParamName`** (string): Query parameter name for tokens in SSE URLs
- **`audiences`** (string[]): Audiences the token is valid for
#### Token Management #### Token Management

View File

@ -48,6 +48,7 @@ describe('MCPOAuthProvider', () => {
tokenUrl: 'https://auth.example.com/token', tokenUrl: 'https://auth.example.com/token',
scopes: ['read', 'write'], scopes: ['read', 'write'],
redirectUri: 'http://localhost:7777/oauth/callback', redirectUri: 'http://localhost:7777/oauth/callback',
audiences: ['https://api.example.com'],
}; };
const mockToken: MCPOAuthToken = { const mockToken: MCPOAuthToken = {
@ -722,6 +723,7 @@ describe('MCPOAuthProvider', () => {
expect(capturedUrl!).toContain('code_challenge_method=S256'); expect(capturedUrl!).toContain('code_challenge_method=S256');
expect(capturedUrl!).toContain('scope=read+write'); expect(capturedUrl!).toContain('scope=read+write');
expect(capturedUrl!).toContain('resource=https%3A%2F%2Fauth.example.com'); expect(capturedUrl!).toContain('resource=https%3A%2F%2Fauth.example.com');
expect(capturedUrl!).toContain('audience=https%3A%2F%2Fapi.example.com');
}); });
it('should correctly append parameters to an authorization URL that already has query params', async () => { it('should correctly append parameters to an authorization URL that already has query params', async () => {

View File

@ -22,6 +22,7 @@ export interface MCPOAuthConfig {
authorizationUrl?: string; authorizationUrl?: string;
tokenUrl?: string; tokenUrl?: string;
scopes?: string[]; scopes?: string[];
audiences?: string[];
redirectUri?: string; redirectUri?: string;
tokenParamName?: string; // For SSE connections, specifies the query parameter name for the token tokenParamName?: string; // For SSE connections, specifies the query parameter name for the token
} }
@ -297,6 +298,10 @@ export class MCPOAuthProvider {
params.append('scope', config.scopes.join(' ')); params.append('scope', config.scopes.join(' '));
} }
if (config.audiences && config.audiences.length > 0) {
params.append('audience', config.audiences.join(' '));
}
// Add resource parameter for MCP OAuth spec compliance // Add resource parameter for MCP OAuth spec compliance
// Use the MCP server URL if provided, otherwise fall back to authorization URL // Use the MCP server URL if provided, otherwise fall back to authorization URL
const resourceUrl = mcpServerUrl || config.authorizationUrl!; const resourceUrl = mcpServerUrl || config.authorizationUrl!;
@ -346,6 +351,10 @@ export class MCPOAuthProvider {
params.append('client_secret', config.clientSecret); params.append('client_secret', config.clientSecret);
} }
if (config.audiences && config.audiences.length > 0) {
params.append('audience', config.audiences.join(' '));
}
// Add resource parameter for MCP OAuth spec compliance // Add resource parameter for MCP OAuth spec compliance
// Use the MCP server URL if provided, otherwise fall back to token URL // Use the MCP server URL if provided, otherwise fall back to token URL
const resourceUrl = mcpServerUrl || config.tokenUrl!; const resourceUrl = mcpServerUrl || config.tokenUrl!;
@ -404,6 +413,10 @@ export class MCPOAuthProvider {
params.append('scope', config.scopes.join(' ')); params.append('scope', config.scopes.join(' '));
} }
if (config.audiences && config.audiences.length > 0) {
params.append('audience', config.audiences.join(' '));
}
// Add resource parameter for MCP OAuth spec compliance // Add resource parameter for MCP OAuth spec compliance
// Use the MCP server URL if provided, otherwise fall back to token URL // Use the MCP server URL if provided, otherwise fall back to token URL
const resourceUrl = mcpServerUrl || tokenUrl; const resourceUrl = mcpServerUrl || tokenUrl;