Skip to content

Commit a172b32

Browse files
authored
feat: support auth block in MCP servers config in agents (#24770)
1 parent a4318f2 commit a172b32

2 files changed

Lines changed: 89 additions & 5 deletions

File tree

packages/core/src/agents/agentLoader.test.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,42 @@ Body`);
493493
});
494494
});
495495

496+
it('should convert mcp_servers with auth block in local agent (google-credentials)', () => {
497+
const markdown = {
498+
kind: 'local' as const,
499+
name: 'spanner-test-agent',
500+
description: 'An agent to test Spanner MCP with auth',
501+
mcp_servers: {
502+
spanner: {
503+
url: 'https://spanner.googleapis.com/mcp',
504+
type: 'http' as const,
505+
auth: {
506+
type: 'google-credentials' as const,
507+
scopes: ['https://www.googleapis.com/auth/cloud-platform'],
508+
},
509+
timeout: 30000,
510+
},
511+
},
512+
system_prompt: 'You are a Spanner test agent.',
513+
};
514+
515+
const result = markdownToAgentDefinition(
516+
markdown,
517+
) as LocalAgentDefinition;
518+
expect(result.kind).toBe('local');
519+
expect(result.mcpServers).toBeDefined();
520+
expect(result.mcpServers!['spanner']).toMatchObject({
521+
url: 'https://spanner.googleapis.com/mcp',
522+
type: 'http',
523+
authProviderType: 'google_credentials',
524+
oauth: {
525+
enabled: true,
526+
scopes: ['https://www.googleapis.com/auth/cloud-platform'],
527+
},
528+
timeout: 30000,
529+
});
530+
});
531+
496532
it('should pass through unknown model names (e.g. auto)', () => {
497533
const markdown = {
498534
kind: 'local' as const,

packages/core/src/agents/agentLoader.ts

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@ import {
1717
DEFAULT_MAX_TIME_MINUTES,
1818
} from './types.js';
1919
import type { A2AAuthConfig } from './auth-provider/types.js';
20-
import { MCPServerConfig } from '../config/config.js';
20+
import {
21+
MCPServerConfig,
22+
AuthProviderType,
23+
type MCPOAuthConfig,
24+
} from '../config/config.js';
2125
import { isValidToolName } from '../tools/tool-names.js';
2226
import { FRONTMATTER_REGEX } from '../skills/skillLoader.js';
2327
import { getErrorMessage } from '../utils/errors.js';
@@ -62,6 +66,22 @@ const mcpServerSchema = z.object({
6266
description: z.string().optional(),
6367
include_tools: z.array(z.string()).optional(),
6468
exclude_tools: z.array(z.string()).optional(),
69+
auth: z
70+
.union([
71+
z.object({
72+
type: z.literal('google-credentials'),
73+
scopes: z.array(z.string()).optional(),
74+
}),
75+
z.object({
76+
type: z.literal('oauth'),
77+
client_id: z.string().optional(),
78+
client_secret: z.string().optional(),
79+
scopes: z.array(z.string()).optional(),
80+
authorization_url: z.string().url().optional(),
81+
token_url: z.string().url().optional(),
82+
}),
83+
])
84+
.optional(),
6585
});
6686

6787
const localAgentSchema = z
@@ -74,9 +94,12 @@ const localAgentSchema = z
7494
.array(
7595
z
7696
.string()
77-
.refine((val) => isValidToolName(val, { allowWildcards: true }), {
78-
message: 'Invalid tool name',
79-
}),
97+
.refine(
98+
(val: string) => isValidToolName(val, { allowWildcards: true }),
99+
{
100+
message: 'Invalid tool name',
101+
},
102+
),
80103
)
81104
.optional(),
82105
mcp_servers: z.record(mcpServerSchema).optional(),
@@ -191,7 +214,7 @@ const remoteAgentJsonSchema = baseRemoteAgentSchema
191214
.extend({
192215
agent_card_url: z.undefined().optional(),
193216
agent_card_json: z.string().refine(
194-
(val) => {
217+
(val: string) => {
195218
try {
196219
JSON.parse(val);
197220
return true;
@@ -511,6 +534,28 @@ export function markdownToAgentDefinition(
511534
const mcpServers: Record<string, MCPServerConfig> = {};
512535
if (markdown.mcp_servers) {
513536
for (const [name, config] of Object.entries(markdown.mcp_servers)) {
537+
let authProviderType: AuthProviderType | undefined = undefined;
538+
let oauth: MCPOAuthConfig | undefined = undefined;
539+
540+
if (config.auth) {
541+
if (config.auth.type === 'google-credentials') {
542+
authProviderType = AuthProviderType.GOOGLE_CREDENTIALS;
543+
oauth = {
544+
enabled: true,
545+
scopes: config.auth.scopes,
546+
};
547+
} else if (config.auth.type === 'oauth') {
548+
oauth = {
549+
enabled: true,
550+
clientId: config.auth.client_id,
551+
clientSecret: config.auth.client_secret,
552+
scopes: config.auth.scopes,
553+
authorizationUrl: config.auth.authorization_url,
554+
tokenUrl: config.auth.token_url,
555+
};
556+
}
557+
}
558+
514559
mcpServers[name] = new MCPServerConfig(
515560
config.command,
516561
config.args,
@@ -526,6 +571,9 @@ export function markdownToAgentDefinition(
526571
config.description,
527572
config.include_tools,
528573
config.exclude_tools,
574+
undefined, // extension
575+
oauth,
576+
authProviderType,
529577
);
530578
}
531579
}

0 commit comments

Comments
 (0)