feat: mcp - support audiences for OAuth2 (#5265)
This commit is contained in:
parent
29c3825604
commit
dadf05809c
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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 () => {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue