feat(mcp): restore Exa websearch support (#549)
* feat(mcp): restore Exa MCP websearch support - Add websearch.ts with Exa remote MCP configuration - Update McpNameSchema to include websearch - Wire websearch MCP into plugin initialization 🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode) * test(mcp): update tests and docs for websearch MCP - Update index.test.ts to verify 3 MCPs (websearch, context7, grep_app) - Add Exa/websearch documentation to README.md MCPs section 🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
This commit is contained in:
@@ -582,6 +582,7 @@ These tools enable agents to reference previous conversations and maintain conti
|
|||||||
- Use camelCase for function names
|
- Use camelCase for function names
|
||||||
```
|
```
|
||||||
- **Online**: Project rules aren't everything. Built-in MCPs for extended capabilities:
|
- **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
|
- **context7**: Official documentation lookup
|
||||||
- **grep_app**: Ultra-fast code search across public GitHub repos (great for finding implementation examples)
|
- **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
|
### 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
|
- **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)
|
- **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
|
```json
|
||||||
{
|
{
|
||||||
"disabled_mcps": ["context7", "grep_app"]
|
"disabled_mcps": ["websearch", "context7", "grep_app"]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -10,9 +10,10 @@ describe("createBuiltinMcps", () => {
|
|||||||
const result = createBuiltinMcps(disabledMcps)
|
const result = createBuiltinMcps(disabledMcps)
|
||||||
|
|
||||||
//#then
|
//#then
|
||||||
|
expect(result).toHaveProperty("websearch")
|
||||||
expect(result).toHaveProperty("context7")
|
expect(result).toHaveProperty("context7")
|
||||||
expect(result).toHaveProperty("grep_app")
|
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", () => {
|
test("should filter out disabled built-in MCPs", () => {
|
||||||
@@ -23,19 +24,21 @@ describe("createBuiltinMcps", () => {
|
|||||||
const result = createBuiltinMcps(disabledMcps)
|
const result = createBuiltinMcps(disabledMcps)
|
||||||
|
|
||||||
//#then
|
//#then
|
||||||
|
expect(result).toHaveProperty("websearch")
|
||||||
expect(result).not.toHaveProperty("context7")
|
expect(result).not.toHaveProperty("context7")
|
||||||
expect(result).toHaveProperty("grep_app")
|
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
|
//#given
|
||||||
const disabledMcps = ["context7", "grep_app"]
|
const disabledMcps = ["websearch", "context7", "grep_app"]
|
||||||
|
|
||||||
//#when
|
//#when
|
||||||
const result = createBuiltinMcps(disabledMcps)
|
const result = createBuiltinMcps(disabledMcps)
|
||||||
|
|
||||||
//#then
|
//#then
|
||||||
|
expect(result).not.toHaveProperty("websearch")
|
||||||
expect(result).not.toHaveProperty("context7")
|
expect(result).not.toHaveProperty("context7")
|
||||||
expect(result).not.toHaveProperty("grep_app")
|
expect(result).not.toHaveProperty("grep_app")
|
||||||
expect(Object.keys(result)).toHaveLength(0)
|
expect(Object.keys(result)).toHaveLength(0)
|
||||||
@@ -49,9 +52,10 @@ describe("createBuiltinMcps", () => {
|
|||||||
const result = createBuiltinMcps(disabledMcps)
|
const result = createBuiltinMcps(disabledMcps)
|
||||||
|
|
||||||
//#then
|
//#then
|
||||||
|
expect(result).toHaveProperty("websearch")
|
||||||
expect(result).not.toHaveProperty("context7")
|
expect(result).not.toHaveProperty("context7")
|
||||||
expect(result).toHaveProperty("grep_app")
|
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", () => {
|
test("should handle empty disabled_mcps by default", () => {
|
||||||
@@ -60,9 +64,10 @@ describe("createBuiltinMcps", () => {
|
|||||||
const result = createBuiltinMcps()
|
const result = createBuiltinMcps()
|
||||||
|
|
||||||
//#then
|
//#then
|
||||||
|
expect(result).toHaveProperty("websearch")
|
||||||
expect(result).toHaveProperty("context7")
|
expect(result).toHaveProperty("context7")
|
||||||
expect(result).toHaveProperty("grep_app")
|
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", () => {
|
test("should only filter built-in MCPs, ignoring unknown names", () => {
|
||||||
@@ -73,8 +78,9 @@ describe("createBuiltinMcps", () => {
|
|||||||
const result = createBuiltinMcps(disabledMcps)
|
const result = createBuiltinMcps(disabledMcps)
|
||||||
|
|
||||||
//#then
|
//#then
|
||||||
|
expect(result).toHaveProperty("websearch")
|
||||||
expect(result).toHaveProperty("context7")
|
expect(result).toHaveProperty("context7")
|
||||||
expect(result).toHaveProperty("grep_app")
|
expect(result).toHaveProperty("grep_app")
|
||||||
expect(Object.keys(result)).toHaveLength(2)
|
expect(Object.keys(result)).toHaveLength(3)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { websearch } from "./websearch"
|
||||||
import { context7 } from "./context7"
|
import { context7 } from "./context7"
|
||||||
import { grep_app } from "./grep-app"
|
import { grep_app } from "./grep-app"
|
||||||
import type { McpName } from "./types"
|
import type { McpName } from "./types"
|
||||||
@@ -5,6 +6,7 @@ import type { McpName } from "./types"
|
|||||||
export { McpNameSchema, type McpName } from "./types"
|
export { McpNameSchema, type McpName } from "./types"
|
||||||
|
|
||||||
const allBuiltinMcps: Record<McpName, { type: "remote"; url: string; enabled: boolean }> = {
|
const allBuiltinMcps: Record<McpName, { type: "remote"; url: string; enabled: boolean }> = {
|
||||||
|
websearch,
|
||||||
context7,
|
context7,
|
||||||
grep_app,
|
grep_app,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { z } from "zod"
|
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<typeof McpNameSchema>
|
export type McpName = z.infer<typeof McpNameSchema>
|
||||||
|
|
||||||
|
|||||||
5
src/mcp/websearch.ts
Normal file
5
src/mcp/websearch.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
export const websearch = {
|
||||||
|
type: "remote" as const,
|
||||||
|
url: "https://mcp.exa.ai/mcp?tools=web_search_exa",
|
||||||
|
enabled: true,
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user