summaryrefslogtreecommitdiff
path: root/packages/core/src
diff options
context:
space:
mode:
authorMikhail Aksenov <[email protected]>2025-08-06 00:02:16 +0200
committerGitHub <[email protected]>2025-08-05 22:02:16 +0000
commitdadf05809c4978455a646ab4ef95421fbe758657 (patch)
treeffb318b766aec91014d90492ad5a2a2077954d24 /packages/core/src
parent29c3825604fdc82b483902bf79f204673e2dfdae (diff)
feat: mcp - support audiences for OAuth2 (#5265)
Diffstat (limited to 'packages/core/src')
-rw-r--r--packages/core/src/mcp/oauth-provider.test.ts2
-rw-r--r--packages/core/src/mcp/oauth-provider.ts13
2 files changed, 15 insertions, 0 deletions
diff --git a/packages/core/src/mcp/oauth-provider.test.ts b/packages/core/src/mcp/oauth-provider.test.ts
index 74eb42c0..3991aecc 100644
--- a/packages/core/src/mcp/oauth-provider.test.ts
+++ b/packages/core/src/mcp/oauth-provider.test.ts
@@ -48,6 +48,7 @@ describe('MCPOAuthProvider', () => {
tokenUrl: 'https://auth.example.com/token',
scopes: ['read', 'write'],
redirectUri: 'http://localhost:7777/oauth/callback',
+ audiences: ['https://api.example.com'],
};
const mockToken: MCPOAuthToken = {
@@ -722,6 +723,7 @@ describe('MCPOAuthProvider', () => {
expect(capturedUrl!).toContain('code_challenge_method=S256');
expect(capturedUrl!).toContain('scope=read+write');
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 () => {
diff --git a/packages/core/src/mcp/oauth-provider.ts b/packages/core/src/mcp/oauth-provider.ts
index 5052e8af..c86478c6 100644
--- a/packages/core/src/mcp/oauth-provider.ts
+++ b/packages/core/src/mcp/oauth-provider.ts
@@ -22,6 +22,7 @@ export interface MCPOAuthConfig {
authorizationUrl?: string;
tokenUrl?: string;
scopes?: string[];
+ audiences?: string[];
redirectUri?: string;
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(' '));
}
+ if (config.audiences && config.audiences.length > 0) {
+ params.append('audience', config.audiences.join(' '));
+ }
+
// Add resource parameter for MCP OAuth spec compliance
// Use the MCP server URL if provided, otherwise fall back to authorization URL
const resourceUrl = mcpServerUrl || config.authorizationUrl!;
@@ -346,6 +351,10 @@ export class MCPOAuthProvider {
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
// Use the MCP server URL if provided, otherwise fall back to token URL
const resourceUrl = mcpServerUrl || config.tokenUrl!;
@@ -404,6 +413,10 @@ export class MCPOAuthProvider {
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
// Use the MCP server URL if provided, otherwise fall back to token URL
const resourceUrl = mcpServerUrl || tokenUrl;