diff --git a/src/mcp/index.ts b/src/mcp/index.ts index db6f0537..1adeff00 100644 --- a/src/mcp/index.ts +++ b/src/mcp/index.ts @@ -1,7 +1,8 @@ -import { websearch } from "./websearch" +import { createWebsearchConfig } from "./websearch" import { context7 } from "./context7" import { grep_app } from "./grep-app" import type { McpName } from "./types" +import type { OhMyOpenCodeConfig } from "../config/schema" export { McpNameSchema, type McpName } from "./types" @@ -13,18 +14,18 @@ type RemoteMcpConfig = { oauth?: false } -const allBuiltinMcps: Record = { - websearch, - context7, - grep_app, -} +export function createBuiltinMcps(disabledMcps: string[] = [], config?: OhMyOpenCodeConfig) { + const allBuiltinMcps: Record = { + websearch: createWebsearchConfig(config?.websearch), + context7, + grep_app, + } -export function createBuiltinMcps(disabledMcps: string[] = []) { const mcps: Record = {} - for (const [name, config] of Object.entries(allBuiltinMcps)) { + for (const [name, mcp] of Object.entries(allBuiltinMcps)) { if (!disabledMcps.includes(name)) { - mcps[name] = config + mcps[name] = mcp } } diff --git a/src/mcp/websearch.ts b/src/mcp/websearch.ts index cc267406..91eddccc 100644 --- a/src/mcp/websearch.ts +++ b/src/mcp/websearch.ts @@ -1,10 +1,44 @@ -export const websearch = { - type: "remote" as const, - url: "https://mcp.exa.ai/mcp?tools=web_search_exa", - enabled: true, - headers: process.env.EXA_API_KEY - ? { "x-api-key": process.env.EXA_API_KEY } - : undefined, - // Disable OAuth auto-detection - Exa uses API key header, not OAuth - oauth: false as const, +import type { WebsearchConfig } from "../config/schema" + +type RemoteMcpConfig = { + type: "remote" + url: string + enabled: boolean + headers?: Record + oauth?: false } + +export function createWebsearchConfig(config?: WebsearchConfig): RemoteMcpConfig { + const provider = config?.provider || "exa" + + if (provider === "tavily") { + const tavilyKey = process.env.TAVILY_API_KEY + if (!tavilyKey) { + throw new Error("TAVILY_API_KEY environment variable is required for Tavily provider") + } + + return { + type: "remote" as const, + url: "https://mcp.tavily.com/mcp/", + enabled: true, + headers: { + Authorization: `Bearer ${tavilyKey}`, + }, + oauth: false as const, + } + } + + // Default to Exa + return { + type: "remote" as const, + url: "https://mcp.exa.ai/mcp?tools=web_search_exa", + enabled: true, + headers: process.env.EXA_API_KEY + ? { "x-api-key": process.env.EXA_API_KEY } + : undefined, + oauth: false as const, + } +} + +// Backward compatibility: export static instance using default config +export const websearch = createWebsearchConfig() diff --git a/src/plugin-handlers/config-handler.ts b/src/plugin-handlers/config-handler.ts index 457e8069..692accf3 100644 --- a/src/plugin-handlers/config-handler.ts +++ b/src/plugin-handlers/config-handler.ts @@ -447,7 +447,7 @@ export function createConfigHandler(deps: ConfigHandlerDeps) { : { servers: {} }; config.mcp = { - ...createBuiltinMcps(pluginConfig.disabled_mcps), + ...createBuiltinMcps(pluginConfig.disabled_mcps, pluginConfig), ...(config.mcp as Record), ...mcpResult.servers, ...pluginComponents.mcpServers,