fix(websearch): use Bearer auth for Exa MCP

Switch from query-param (?exaApiKey=...) to Authorization: Bearer header
for Exa MCP authentication. The MCP SDK's SSE endpoint resolution discards
query parameters when the server replies with a relative path, causing
EXA_API_KEY to be silently lost and falling back to rate-limited free tier.

Bearer auth via header survives URL resolution and is consistent with the
Tavily MCP config pattern already in use.

Fixes #3763
Relands #4090 (CLA unsigned by original author)

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Minsoo Choi <Neo1228@users.noreply.github.com>
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
YeonGyu-Kim
2026-05-18 13:28:31 +09:00
parent 5555dbfc67
commit 5ae0db042d
2 changed files with 35 additions and 4 deletions
+33
View File
@@ -54,3 +54,36 @@ describe("createWebsearchConfig Tavily handling", () => {
expect(config?.url).toBe("https://mcp.tavily.com/mcp/")
})
})
describe("createWebsearchConfig Exa handling", () => {
test("keeps EXA_API_KEY out of URL query params and sends bearer auth header", () => {
process.env.EXA_API_KEY = "exa-secret"
const config = createWebsearchConfig({ provider: "exa" })
expect(config).toEqual({
type: "remote",
url: "https://mcp.exa.ai/mcp?tools=web_search_exa",
enabled: true,
headers: {
Authorization: "Bearer exa-secret",
},
oauth: false,
})
expect(config?.url).not.toContain("exaApiKey")
expect(config?.headers).not.toHaveProperty("x-api-key")
})
test("uses unauthenticated Exa URL when EXA_API_KEY is missing", () => {
delete process.env.EXA_API_KEY
const config = createWebsearchConfig({ provider: "exa" })
expect(config).toEqual({
type: "remote",
url: "https://mcp.exa.ai/mcp?tools=web_search_exa",
enabled: true,
oauth: false,
})
})
})
+2 -4
View File
@@ -32,11 +32,9 @@ export function createWebsearchConfig(config?: WebsearchConfig): RemoteMcpConfig
return {
type: "remote" as const,
url: process.env.EXA_API_KEY
? `https://mcp.exa.ai/mcp?tools=web_search_exa&exaApiKey=${encodeURIComponent(process.env.EXA_API_KEY)}`
: "https://mcp.exa.ai/mcp?tools=web_search_exa",
url: "https://mcp.exa.ai/mcp?tools=web_search_exa",
enabled: true,
...(process.env.EXA_API_KEY ? { headers: { "x-api-key": process.env.EXA_API_KEY } } : {}),
...(process.env.EXA_API_KEY ? { headers: { Authorization: `Bearer ${process.env.EXA_API_KEY}` } } : {}),
oauth: false as const,
}
}