diff --git a/README.md b/README.md index 09196ac..f779de3 100644 --- a/README.md +++ b/README.md @@ -582,6 +582,7 @@ These tools enable agents to reference previous conversations and maintain conti - Use camelCase for function names ``` - **Online**: Project rules aren't everything. Built-in MCPs for extended capabilities: + - **websearch**: Real-time web search powered by [Exa AI](https://exa.ai) - **context7**: Official documentation lookup - **grep_app**: Ultra-fast code search across public GitHub repos (great for finding implementation examples) @@ -983,8 +984,9 @@ Available hooks: `todo-continuation-enforcer`, `context-window-monitor`, `sessio ### MCPs -Context7 and grep.app MCP enabled by default. +Exa, Context7 and grep.app MCP enabled by default. +- **websearch**: Real-time web search powered by [Exa AI](https://exa.ai) - searches the web and returns relevant content - **context7**: Fetches up-to-date official documentation for libraries - **grep_app**: Ultra-fast code search across millions of public GitHub repositories via [grep.app](https://grep.app) @@ -992,7 +994,7 @@ Don't want them? Disable via `disabled_mcps` in `~/.config/opencode/oh-my-openco ```json { - "disabled_mcps": ["context7", "grep_app"] + "disabled_mcps": ["websearch", "context7", "grep_app"] } ``` diff --git a/src/mcp/index.test.ts b/src/mcp/index.test.ts index 287ee0a..5e648b2 100644 --- a/src/mcp/index.test.ts +++ b/src/mcp/index.test.ts @@ -10,9 +10,10 @@ describe("createBuiltinMcps", () => { const result = createBuiltinMcps(disabledMcps) //#then + expect(result).toHaveProperty("websearch") expect(result).toHaveProperty("context7") expect(result).toHaveProperty("grep_app") - expect(Object.keys(result)).toHaveLength(2) + expect(Object.keys(result)).toHaveLength(3) }) test("should filter out disabled built-in MCPs", () => { @@ -23,19 +24,21 @@ describe("createBuiltinMcps", () => { const result = createBuiltinMcps(disabledMcps) //#then + expect(result).toHaveProperty("websearch") expect(result).not.toHaveProperty("context7") expect(result).toHaveProperty("grep_app") - expect(Object.keys(result)).toHaveLength(1) + expect(Object.keys(result)).toHaveLength(2) }) - test("should filter out both built-in MCPs when both disabled", () => { + test("should filter out all built-in MCPs when all disabled", () => { //#given - const disabledMcps = ["context7", "grep_app"] + const disabledMcps = ["websearch", "context7", "grep_app"] //#when const result = createBuiltinMcps(disabledMcps) //#then + expect(result).not.toHaveProperty("websearch") expect(result).not.toHaveProperty("context7") expect(result).not.toHaveProperty("grep_app") expect(Object.keys(result)).toHaveLength(0) @@ -49,9 +52,10 @@ describe("createBuiltinMcps", () => { const result = createBuiltinMcps(disabledMcps) //#then + expect(result).toHaveProperty("websearch") expect(result).not.toHaveProperty("context7") expect(result).toHaveProperty("grep_app") - expect(Object.keys(result)).toHaveLength(1) + expect(Object.keys(result)).toHaveLength(2) }) test("should handle empty disabled_mcps by default", () => { @@ -60,9 +64,10 @@ describe("createBuiltinMcps", () => { const result = createBuiltinMcps() //#then + expect(result).toHaveProperty("websearch") expect(result).toHaveProperty("context7") expect(result).toHaveProperty("grep_app") - expect(Object.keys(result)).toHaveLength(2) + expect(Object.keys(result)).toHaveLength(3) }) test("should only filter built-in MCPs, ignoring unknown names", () => { @@ -73,8 +78,9 @@ describe("createBuiltinMcps", () => { const result = createBuiltinMcps(disabledMcps) //#then + expect(result).toHaveProperty("websearch") expect(result).toHaveProperty("context7") expect(result).toHaveProperty("grep_app") - expect(Object.keys(result)).toHaveLength(2) + expect(Object.keys(result)).toHaveLength(3) }) }) diff --git a/src/mcp/index.ts b/src/mcp/index.ts index 2449e18..a3ec2da 100644 --- a/src/mcp/index.ts +++ b/src/mcp/index.ts @@ -1,3 +1,4 @@ +import { websearch } from "./websearch" import { context7 } from "./context7" import { grep_app } from "./grep-app" import type { McpName } from "./types" @@ -5,6 +6,7 @@ import type { McpName } from "./types" export { McpNameSchema, type McpName } from "./types" const allBuiltinMcps: Record = { + websearch, context7, grep_app, } diff --git a/src/mcp/types.ts b/src/mcp/types.ts index 61d9672..b3a24b8 100644 --- a/src/mcp/types.ts +++ b/src/mcp/types.ts @@ -1,6 +1,6 @@ import { z } from "zod" -export const McpNameSchema = z.enum(["context7", "grep_app"]) +export const McpNameSchema = z.enum(["websearch", "context7", "grep_app"]) export type McpName = z.infer diff --git a/src/mcp/websearch.ts b/src/mcp/websearch.ts new file mode 100644 index 0000000..60584e9 --- /dev/null +++ b/src/mcp/websearch.ts @@ -0,0 +1,5 @@ +export const websearch = { + type: "remote" as const, + url: "https://mcp.exa.ai/mcp?tools=web_search_exa", + enabled: true, +}