Skip to content

Commit e57b51c

Browse files
committed
MCP support
1 parent 75b54e4 commit e57b51c

38 files changed

+890
-182
lines changed

.agents/types/agent-definition.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,12 @@
1515
*/
1616

1717
import type * as Tools from './tools'
18-
import type { Message, ToolResultOutput, JsonObjectSchema } from './util-types'
18+
import type {
19+
Message,
20+
ToolResultOutput,
21+
JsonObjectSchema,
22+
MCPConfig,
23+
} from './util-types'
1924
type ToolName = Tools.ToolName
2025

2126
// ============================================================================
@@ -70,7 +75,17 @@ export interface AgentDefinition {
7075
// Tools and Subagents
7176
// ============================================================================
7277

73-
/** Tools this agent can use. */
78+
/** MCP servers by name. Names cannot contain `/`. */
79+
mcpServers?: Record<string, MCPConfig>
80+
81+
/**
82+
* Tools this agent can use.
83+
*
84+
* By default, all tools are available from any specified MCP server. In
85+
* order to limit the tools from a specific MCP server, add the tool name(s)
86+
* in the format `'mcpServerName/toolName1'`, `'mcpServerName/toolName2'`,
87+
* etc.
88+
*/
7489
toolNames?: (ToolName | (string & {}))[]
7590

7691
/** Other agents this agent can spawn, like 'codebuff/file-picker@0.0.1'.

.agents/types/util-types.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,3 +202,26 @@ export const messageSchema = z
202202
)
203203
export type Message = z.infer<typeof messageSchema>
204204

205+
// ===== MCP Server Types =====
206+
207+
export const mcpConfigStdioSchema = z.strictObject({
208+
type: z.literal('stdio').default('stdio'),
209+
command: z.string(),
210+
args: z
211+
.string()
212+
.array()
213+
.default(() => []),
214+
env: z.record(z.string(), z.string()).default(() => ({})),
215+
})
216+
217+
export const mcpConfigRemoteSchema = z.strictObject({
218+
type: z.enum(['http', 'sse']).default('http'),
219+
url: z.string(),
220+
params: z.record(z.string(), z.string()).default(() => ({})),
221+
})
222+
223+
export const mcpConfigSchema = z.union([
224+
mcpConfigRemoteSchema,
225+
mcpConfigStdioSchema,
226+
])
227+
export type MCPConfig = z.input<typeof mcpConfigSchema>

backend/src/__tests__/agent-id-resolution.test.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ describe('Agent ID Resolution', () => {
1818
systemPrompt: 'Test',
1919
instructionsPrompt: 'Test',
2020
stepPrompt: 'Test',
21+
mcpServers: {},
2122
toolNames: ['end_turn'],
2223
spawnableAgents: [],
2324
outputMode: 'last_message',
@@ -32,6 +33,7 @@ describe('Agent ID Resolution', () => {
3233
systemPrompt: 'Test',
3334
instructionsPrompt: 'Test',
3435
stepPrompt: 'Test',
36+
mcpServers: {},
3537
toolNames: ['find_files'],
3638
spawnableAgents: [],
3739
outputMode: 'last_message',
@@ -47,6 +49,7 @@ describe('Agent ID Resolution', () => {
4749
systemPrompt: 'Test',
4850
instructionsPrompt: 'Test',
4951
stepPrompt: 'Test',
52+
mcpServers: {},
5053
toolNames: ['end_turn'],
5154
spawnableAgents: [],
5255
outputMode: 'last_message',
@@ -61,6 +64,7 @@ describe('Agent ID Resolution', () => {
6164
systemPrompt: 'Test',
6265
instructionsPrompt: 'Test',
6366
stepPrompt: 'Test',
67+
mcpServers: {},
6468
toolNames: ['end_turn'],
6569
spawnableAgents: [],
6670
outputMode: 'last_message',
@@ -76,6 +80,7 @@ describe('Agent ID Resolution', () => {
7680
systemPrompt: 'Test',
7781
instructionsPrompt: 'Test',
7882
stepPrompt: 'Test',
83+
mcpServers: {},
7984
toolNames: ['end_turn'],
8085
spawnableAgents: [],
8186
outputMode: 'last_message',
@@ -145,6 +150,7 @@ describe('Agent ID Resolution', () => {
145150
systemPrompt: 'Test',
146151
instructionsPrompt: 'Test',
147152
stepPrompt: 'Test',
153+
mcpServers: {},
148154
toolNames: ['end_turn'],
149155
spawnableAgents: [],
150156
outputMode: 'last_message',
@@ -171,6 +177,7 @@ describe('Agent ID Resolution', () => {
171177
systemPrompt: 'Test',
172178
instructionsPrompt: 'Test',
173179
stepPrompt: 'Test',
180+
mcpServers: {},
174181
toolNames: ['end_turn'],
175182
spawnableAgents: [],
176183
outputMode: 'last_message',

backend/src/__tests__/agent-registry.test.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ const mockStaticTemplates: Record<string, AgentTemplate> = {
3333
systemPrompt: 'Test',
3434
instructionsPrompt: 'Test',
3535
stepPrompt: 'Test',
36+
mcpServers: {},
3637
toolNames: ['end_turn'],
3738
spawnableAgents: [],
3839
outputMode: 'last_message',
@@ -47,6 +48,7 @@ const mockStaticTemplates: Record<string, AgentTemplate> = {
4748
systemPrompt: 'Test',
4849
instructionsPrompt: 'Test',
4950
stepPrompt: 'Test',
51+
mcpServers: {},
5052
toolNames: ['find_files'],
5153
spawnableAgents: [],
5254
outputMode: 'last_message',
@@ -105,7 +107,6 @@ describe('Agent Registry', () => {
105107
warn: () => {},
106108
},
107109
}))
108-
109110
})
110111
let mockFileContext: ProjectFileContext
111112

@@ -154,7 +155,6 @@ describe('Agent Registry', () => {
154155
warn: () => {},
155156
},
156157
}))
157-
158158
})
159159

160160
beforeEach(async () => {
@@ -230,6 +230,7 @@ describe('Agent Registry', () => {
230230
systemPrompt: 'Test',
231231
instructionsPrompt: 'Test',
232232
stepPrompt: 'Test',
233+
mcpServers: {},
233234
toolNames: ['end_turn'],
234235
spawnableAgents: [],
235236
outputMode: 'last_message',
@@ -321,6 +322,7 @@ describe('Agent Registry', () => {
321322
systemPrompt: 'Local system prompt',
322323
instructionsPrompt: 'Local instructions',
323324
stepPrompt: 'Local step prompt',
325+
mcpServers: {},
324326
toolNames: ['end_turn'],
325327
spawnableAgents: [],
326328
outputMode: 'last_message',

backend/src/__tests__/cost-aggregation.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ describe('Cost Aggregation System', () => {
143143
}
144144

145145
// Mock executeAgent to return results with different credit costs
146-
const mockExecuteAgent = spyOn(spawnAgentUtils, 'executeAgent')
146+
const mockExecuteAgent = spyOn(spawnAgentUtils, 'executeSubagent')
147147
.mockResolvedValueOnce({
148148
agentState: {
149149
...getInitialAgentState(),
@@ -215,7 +215,7 @@ describe('Cost Aggregation System', () => {
215215
}
216216

217217
// Mock executeAgent to return success and failure with partial costs
218-
const mockExecuteAgent = spyOn(spawnAgentUtils, 'executeAgent')
218+
const mockExecuteAgent = spyOn(spawnAgentUtils, 'executeSubagent')
219219
.mockResolvedValueOnce({
220220
agentState: {
221221
...getInitialAgentState(),
@@ -370,7 +370,7 @@ describe('Cost Aggregation System', () => {
370370
sendSubagentChunk: () => {},
371371
}
372372

373-
const mockExecuteAgent = spyOn(spawnAgentUtils, 'executeAgent')
373+
const mockExecuteAgent = spyOn(spawnAgentUtils, 'executeSubagent')
374374
.mockResolvedValueOnce({
375375
agentState: {
376376
...getInitialAgentState(),

backend/src/__tests__/loop-agent-steps.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ describe('loopAgentSteps - runAgentStep vs runProgrammaticStep behavior', () =>
130130
inputSchema: {},
131131
outputMode: 'structured_output',
132132
includeMessageHistory: true,
133+
mcpServers: {},
133134
toolNames: ['read_files', 'write_file', 'end_turn'],
134135
spawnableAgents: [],
135136
systemPrompt: 'Test system prompt',

backend/src/__tests__/main-prompt.integration.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,7 @@ export function getMessagesSubset(messages: Message[], otherTokens: number) {
485485
spawnerPrompt: '',
486486
model: 'gpt-4o-mini',
487487
includeMessageHistory: true,
488+
mcpServers: {},
488489
toolNames: ['write_file', 'run_terminal_command'],
489490
spawnableAgents: [],
490491
systemPrompt: '',

backend/src/__tests__/main-prompt.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,6 @@ describe('mainPrompt', () => {
151151
userInputId: string,
152152
toolName: string,
153153
input: Record<string, any>,
154-
timeout: number = 30_000,
155154
) => {
156155
return {
157156
output: [
@@ -317,6 +316,7 @@ describe('mainPrompt', () => {
317316
spawnerPrompt: '',
318317
model: 'gpt-4o-mini',
319318
includeMessageHistory: true,
319+
mcpServers: {},
320320
toolNames: ['write_file', 'run_terminal_command'],
321321
spawnableAgents: [],
322322
systemPrompt: '',
@@ -331,6 +331,7 @@ describe('mainPrompt', () => {
331331
spawnerPrompt: '',
332332
model: 'gpt-4o',
333333
includeMessageHistory: true,
334+
mcpServers: {},
334335
toolNames: ['write_file', 'run_terminal_command'],
335336
spawnableAgents: [],
336337
systemPrompt: '',

backend/src/__tests__/malformed-tool-call.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ describe('malformed tool call error handling', () => {
6060
inputSchema: {},
6161
outputMode: 'all_messages' as const,
6262
includeMessageHistory: true,
63+
mcpServers: {},
6364
toolNames: ['read_files', 'end_turn'],
6465
spawnableAgents: [],
6566
systemPrompt: 'Test system prompt',

backend/src/__tests__/run-agent-step-tools.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ describe('runAgentStep - set_output tool', () => {
5858
inputSchema: {},
5959
outputMode: 'structured_output' as const,
6060
includeMessageHistory: true,
61+
mcpServers: {},
6162
toolNames: ['set_output', 'end_turn'],
6263
spawnableAgents: [],
6364
systemPrompt: 'Test system prompt',
@@ -347,6 +348,7 @@ describe('runAgentStep - set_output tool', () => {
347348
inputSchema: {},
348349
outputMode: 'structured_output' as const,
349350
includeMessageHistory: true,
351+
mcpServers: {},
350352
toolNames: ['read_files', 'end_turn'],
351353
spawnableAgents: [],
352354
systemPrompt: 'Test system prompt',
@@ -466,6 +468,7 @@ describe('runAgentStep - set_output tool', () => {
466468
inputSchema: {},
467469
outputMode: 'structured_output' as const,
468470
includeMessageHistory: true,
471+
mcpServers: {},
469472
toolNames: ['set_messages', 'end_turn'],
470473
spawnableAgents: [],
471474
systemPrompt: 'Delete messages system prompt',
@@ -516,6 +519,7 @@ describe('runAgentStep - set_output tool', () => {
516519
inputSchema: {},
517520
outputMode: 'structured_output' as const,
518521
includeMessageHistory: true,
522+
mcpServers: {},
519523
toolNames: ['spawn_agent_inline', 'end_turn'],
520524
spawnableAgents: ['message-deleter-agent'],
521525
systemPrompt: 'Parent system prompt',

0 commit comments

Comments
 (0)