fix: handle invalid mcp urls (#25019)

This commit is contained in:
Luke Parker
2026-04-30 09:32:26 +10:00
committed by GitHub
parent 12cbfe5b64
commit ea89925042

View File

@@ -114,6 +114,11 @@ function isMcpConfigured(entry: McpEntry): entry is ConfigMCP.Info {
const sanitize = (s: string) => s.replace(/[^a-zA-Z0-9_-]/g, "_")
function remoteURL(key: string, value: string) {
if (URL.canParse(value)) return new URL(value)
log.warn("invalid remote mcp url", { key })
}
// Convert MCP tool definition to AI SDK Tool type
function convertMcpTool(mcpTool: MCPToolDef, client: MCPClient, timeout?: number): Tool {
const inputSchema = mcpTool.inputSchema
@@ -267,6 +272,13 @@ export const layer = Layer.effect(
) {
const oauthDisabled = mcp.oauth === false
const oauthConfig = typeof mcp.oauth === "object" ? mcp.oauth : undefined
const url = remoteURL(key, mcp.url)
if (!url) {
return {
client: undefined as MCPClient | undefined,
status: { status: "failed" as const, error: `Invalid MCP URL for "${key}"` },
}
}
let authProvider: McpOAuthProvider | undefined
if (!oauthDisabled) {
@@ -291,14 +303,14 @@ export const layer = Layer.effect(
const transports: Array<{ name: string; transport: TransportWithAuth }> = [
{
name: "StreamableHTTP",
transport: new StreamableHTTPClientTransport(new URL(mcp.url), {
transport: new StreamableHTTPClientTransport(url, {
authProvider,
requestInit: mcp.headers ? { headers: mcp.headers } : undefined,
}),
},
{
name: "SSE",
transport: new SSEClientTransport(new URL(mcp.url), {
transport: new SSEClientTransport(url, {
authProvider,
requestInit: mcp.headers ? { headers: mcp.headers } : undefined,
}),
@@ -722,6 +734,8 @@ export const layer = Layer.effect(
if (!mcpConfig) throw new Error(`MCP server ${mcpName} not found or disabled`)
if (mcpConfig.type !== "remote") throw new Error(`MCP server ${mcpName} is not a remote server`)
if (mcpConfig.oauth === false) throw new Error(`MCP server ${mcpName} has OAuth explicitly disabled`)
const url = remoteURL(mcpName, mcpConfig.url)
if (!url) throw new Error(`Invalid MCP URL for "${mcpName}"`)
// OAuth config is optional - if not provided, we'll use auto-discovery
const oauthConfig = typeof mcpConfig.oauth === "object" ? mcpConfig.oauth : undefined
@@ -751,7 +765,7 @@ export const layer = Layer.effect(
auth,
)
const transport = new StreamableHTTPClientTransport(new URL(mcpConfig.url), { authProvider })
const transport = new StreamableHTTPClientTransport(url, { authProvider })
return yield* Effect.tryPromise({
try: () => {