From fbd8aaad5730c9c55a2c9c234729854061960c90 Mon Sep 17 00:00:00 2001 From: Abhi <43648792+abhipatel12@users.noreply.github.com> Date: Tue, 28 Apr 2026 17:57:30 -0400 Subject: [PATCH] fix(core): add missing oauth fields support in subagent parsing (#26141) --- packages/core/src/agents/agentLoader.test.ts | 64 +++++++++++++++++++ packages/core/src/agents/agentLoader.ts | 20 ++++++ .../core/src/agents/auth-provider/types.ts | 5 ++ 3 files changed, 89 insertions(+) diff --git a/packages/core/src/agents/agentLoader.test.ts b/packages/core/src/agents/agentLoader.test.ts index f80a1e8cb3..01e4dbe8d3 100644 --- a/packages/core/src/agents/agentLoader.test.ts +++ b/packages/core/src/agents/agentLoader.test.ts @@ -529,6 +529,59 @@ Body`); }); }); + it('should convert mcp_servers with auth block in local agent (oauth with full fields)', () => { + const markdown = { + kind: 'local' as const, + name: 'oauth-test-agent', + description: 'An agent to test OAuth MCP with full fields', + mcp_servers: { + 'test-server': { + url: 'https://api.example.com/mcp', + type: 'http' as const, + auth: { + type: 'oauth' as const, + client_id: 'my-client-id', + client_secret: 'my-client-secret', + scopes: ['read', 'write'], + authorization_url: 'https://auth.example.com/authorize', + token_url: 'https://auth.example.com/token', + issuer: 'https://auth.example.com', + audiences: ['audience1'], + redirect_uri: 'http://localhost:8080/callback', + token_param_name: 'access_token', + registration_url: 'https://auth.example.com/register', + }, + timeout: 30000, + }, + }, + system_prompt: 'You are a test agent.', + }; + + const result = markdownToAgentDefinition( + markdown, + ) as LocalAgentDefinition; + expect(result.kind).toBe('local'); + expect(result.mcpServers).toBeDefined(); + expect(result.mcpServers!['test-server']).toMatchObject({ + url: 'https://api.example.com/mcp', + type: 'http', + oauth: { + enabled: true, + clientId: 'my-client-id', + clientSecret: 'my-client-secret', + scopes: ['read', 'write'], + authorizationUrl: 'https://auth.example.com/authorize', + tokenUrl: 'https://auth.example.com/token', + issuer: 'https://auth.example.com', + audiences: ['audience1'], + redirectUri: 'http://localhost:8080/callback', + tokenParamName: 'access_token', + registrationUrl: 'https://auth.example.com/register', + }, + timeout: 30000, + }); + }); + it('should pass through unknown model names (e.g. auto)', () => { const markdown = { kind: 'local' as const, @@ -886,6 +939,12 @@ auth: - profile authorization_url: https://auth.example.com/authorize token_url: https://auth.example.com/token + issuer: https://auth.example.com + audiences: + - audience1 + redirect_uri: http://localhost:8080/callback + token_param_name: access_token + registration_url: https://auth.example.com/register --- `); const result = await parseAgentMarkdown(filePath); @@ -900,6 +959,11 @@ auth: scopes: ['openid', 'profile'], authorization_url: 'https://auth.example.com/authorize', token_url: 'https://auth.example.com/token', + issuer: 'https://auth.example.com', + audiences: ['audience1'], + redirect_uri: 'http://localhost:8080/callback', + token_param_name: 'access_token', + registration_url: 'https://auth.example.com/register', }, }); }); diff --git a/packages/core/src/agents/agentLoader.ts b/packages/core/src/agents/agentLoader.ts index 4c5e771af9..940acde38f 100644 --- a/packages/core/src/agents/agentLoader.ts +++ b/packages/core/src/agents/agentLoader.ts @@ -79,6 +79,11 @@ const mcpServerSchema = z.object({ scopes: z.array(z.string()).optional(), authorization_url: z.string().url().optional(), token_url: z.string().url().optional(), + issuer: z.string().url().optional(), + audiences: z.array(z.string()).optional(), + redirect_uri: z.string().url().optional(), + token_param_name: z.string().optional(), + registration_url: z.string().url().optional(), }), ]) .optional(), @@ -148,6 +153,11 @@ const oauth2AuthSchema = z.object({ scopes: z.array(z.string()).optional(), authorization_url: z.string().url().optional(), token_url: z.string().url().optional(), + issuer: z.string().url().optional(), + audiences: z.array(z.string()).optional(), + redirect_uri: z.string().url().optional(), + token_param_name: z.string().optional(), + registration_url: z.string().url().optional(), }); const authConfigSchema = z @@ -459,6 +469,11 @@ function convertFrontmatterAuthToConfig( scopes: frontmatter.scopes, authorization_url: frontmatter.authorization_url, token_url: frontmatter.token_url, + issuer: frontmatter.issuer, + audiences: frontmatter.audiences, + redirect_uri: frontmatter.redirect_uri, + token_param_name: frontmatter.token_param_name, + registration_url: frontmatter.registration_url, }; default: { @@ -552,6 +567,11 @@ export function markdownToAgentDefinition( scopes: config.auth.scopes, authorizationUrl: config.auth.authorization_url, tokenUrl: config.auth.token_url, + issuer: config.auth.issuer, + audiences: config.auth.audiences, + redirectUri: config.auth.redirect_uri, + tokenParamName: config.auth.token_param_name, + registrationUrl: config.auth.registration_url, }; } } diff --git a/packages/core/src/agents/auth-provider/types.ts b/packages/core/src/agents/auth-provider/types.ts index 0808f54ae2..6ba3bbbd43 100644 --- a/packages/core/src/agents/auth-provider/types.ts +++ b/packages/core/src/agents/auth-provider/types.ts @@ -77,6 +77,11 @@ export interface OAuth2AuthConfig extends BaseAuthConfig { authorization_url?: string; /** Override or provide the token endpoint URL. Discovered from agent card if omitted. */ token_url?: string; + issuer?: string; + audiences?: string[]; + redirect_uri?: string; + token_param_name?: string; + registration_url?: string; } /** Client config corresponding to OpenIdConnectSecurityScheme. */