fix: honor per-server MCP timeouts (#8706)
This commit is contained in:
@@ -395,9 +395,7 @@ export namespace Config {
|
|||||||
.int()
|
.int()
|
||||||
.positive()
|
.positive()
|
||||||
.optional()
|
.optional()
|
||||||
.describe(
|
.describe("Timeout in ms for MCP server requests. Defaults to 5000 (5 seconds) if not specified."),
|
||||||
"Timeout in ms for fetching tools from the MCP server. Defaults to 5000 (5 seconds) if not specified.",
|
|
||||||
),
|
|
||||||
})
|
})
|
||||||
.strict()
|
.strict()
|
||||||
.meta({
|
.meta({
|
||||||
@@ -436,9 +434,7 @@ export namespace Config {
|
|||||||
.int()
|
.int()
|
||||||
.positive()
|
.positive()
|
||||||
.optional()
|
.optional()
|
||||||
.describe(
|
.describe("Timeout in ms for MCP server requests. Defaults to 5000 (5 seconds) if not specified."),
|
||||||
"Timeout in ms for fetching tools from the MCP server. Defaults to 5000 (5 seconds) if not specified.",
|
|
||||||
),
|
|
||||||
})
|
})
|
||||||
.strict()
|
.strict()
|
||||||
.meta({
|
.meta({
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ export namespace MCP {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Convert MCP tool definition to AI SDK Tool type
|
// Convert MCP tool definition to AI SDK Tool type
|
||||||
async function convertMcpTool(mcpTool: MCPToolDef, client: MCPClient): Promise<Tool> {
|
async function convertMcpTool(mcpTool: MCPToolDef, client: MCPClient, timeout?: number): Promise<Tool> {
|
||||||
const inputSchema = mcpTool.inputSchema
|
const inputSchema = mcpTool.inputSchema
|
||||||
|
|
||||||
// Spread first, then override type to ensure it's always "object"
|
// Spread first, then override type to ensure it's always "object"
|
||||||
@@ -119,7 +119,6 @@ export namespace MCP {
|
|||||||
properties: (inputSchema.properties ?? {}) as JSONSchema7["properties"],
|
properties: (inputSchema.properties ?? {}) as JSONSchema7["properties"],
|
||||||
additionalProperties: false,
|
additionalProperties: false,
|
||||||
}
|
}
|
||||||
const config = await Config.get()
|
|
||||||
|
|
||||||
return dynamicTool({
|
return dynamicTool({
|
||||||
description: mcpTool.description ?? "",
|
description: mcpTool.description ?? "",
|
||||||
@@ -133,7 +132,7 @@ export namespace MCP {
|
|||||||
CallToolResultSchema,
|
CallToolResultSchema,
|
||||||
{
|
{
|
||||||
resetTimeoutOnProgress: true,
|
resetTimeoutOnProgress: true,
|
||||||
timeout: config.experimental?.mcp_timeout,
|
timeout,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@@ -556,7 +555,10 @@ export namespace MCP {
|
|||||||
export async function tools() {
|
export async function tools() {
|
||||||
const result: Record<string, Tool> = {}
|
const result: Record<string, Tool> = {}
|
||||||
const s = await state()
|
const s = await state()
|
||||||
|
const cfg = await Config.get()
|
||||||
|
const config = cfg.mcp ?? {}
|
||||||
const clientsSnapshot = await clients()
|
const clientsSnapshot = await clients()
|
||||||
|
const defaultTimeout = cfg.experimental?.mcp_timeout
|
||||||
|
|
||||||
for (const [clientName, client] of Object.entries(clientsSnapshot)) {
|
for (const [clientName, client] of Object.entries(clientsSnapshot)) {
|
||||||
// Only include tools from connected MCPs (skip disabled ones)
|
// Only include tools from connected MCPs (skip disabled ones)
|
||||||
@@ -577,10 +579,13 @@ export namespace MCP {
|
|||||||
if (!toolsResult) {
|
if (!toolsResult) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
const mcpConfig = config[clientName]
|
||||||
|
const entry = isMcpConfigured(mcpConfig) ? mcpConfig : undefined
|
||||||
|
const timeout = entry?.timeout ?? defaultTimeout
|
||||||
for (const mcpTool of toolsResult.tools) {
|
for (const mcpTool of toolsResult.tools) {
|
||||||
const sanitizedClientName = clientName.replace(/[^a-zA-Z0-9_-]/g, "_")
|
const sanitizedClientName = clientName.replace(/[^a-zA-Z0-9_-]/g, "_")
|
||||||
const sanitizedToolName = mcpTool.name.replace(/[^a-zA-Z0-9_-]/g, "_")
|
const sanitizedToolName = mcpTool.name.replace(/[^a-zA-Z0-9_-]/g, "_")
|
||||||
result[sanitizedClientName + "_" + sanitizedToolName] = await convertMcpTool(mcpTool, client)
|
result[sanitizedClientName + "_" + sanitizedToolName] = await convertMcpTool(mcpTool, client, timeout)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
|
|||||||
Reference in New Issue
Block a user