5ae0db042d
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>
43 lines
1.1 KiB
TypeScript
43 lines
1.1 KiB
TypeScript
import type { WebsearchConfig } from "../config/schema"
|
|
import { log } from "../shared/logger"
|
|
|
|
type RemoteMcpConfig = {
|
|
type: "remote"
|
|
url: string
|
|
enabled: boolean
|
|
headers?: Record<string, string>
|
|
oauth?: false
|
|
}
|
|
|
|
export function createWebsearchConfig(config?: WebsearchConfig): RemoteMcpConfig | undefined {
|
|
const provider = config?.provider || "exa"
|
|
|
|
if (provider === "tavily") {
|
|
const tavilyKey = process.env.TAVILY_API_KEY
|
|
if (!tavilyKey) {
|
|
log("[websearch] Tavily API key not found, skipping websearch MCP")
|
|
return undefined
|
|
}
|
|
|
|
return {
|
|
type: "remote" as const,
|
|
url: "https://mcp.tavily.com/mcp/",
|
|
enabled: true,
|
|
headers: {
|
|
Authorization: `Bearer ${tavilyKey}`,
|
|
},
|
|
oauth: false as const,
|
|
}
|
|
}
|
|
|
|
return {
|
|
type: "remote" as const,
|
|
url: "https://mcp.exa.ai/mcp?tools=web_search_exa",
|
|
enabled: true,
|
|
...(process.env.EXA_API_KEY ? { headers: { Authorization: `Bearer ${process.env.EXA_API_KEY}` } } : {}),
|
|
oauth: false as const,
|
|
}
|
|
}
|
|
|
|
export const websearch = createWebsearchConfig()
|