diff --git a/README.en.md b/README.en.md index 34039c1..fcae1c6 100644 --- a/README.en.md +++ b/README.en.md @@ -4,6 +4,7 @@ English | [한국어](README.ko.md) - [Oh My OpenCode](#oh-my-opencode) - [Installation](#installation) + - [Configuration](#configuration) - [TL;DR](#tldr) - [Why OpenCode \& Why Oh My OpenCode](#why-opencode--why-oh-my-opencode) - [Features](#features) @@ -43,6 +44,20 @@ Add to `~/.config/opencode/opencode.json`: } ``` +## Configuration + +You can configure Oh My OpenCode by creating a `oh-my-opencode.json` (or `.oh-my-opencode.json`) file in your project root. + +### Disable specific MCPs + +If you want to disable specific built-in MCPs, you can use the `disabled_mcps` option. + +```json +{ + "disabled_mcps": ["context7", "websearch_exa"] +} +``` + ## TL;DR - **Model Setup Required** @@ -120,7 +135,8 @@ I believe in the right tool for the job. For your wallet's sake, use CLIProxyAPI #### Built-in MCPs -- **websearch_exa**: Exa AI web search. Performs real-time web searches and content scraping. Returns LLM-optimized context from relevant websites. +- **websearch_exa**: Exa AI web search. Performs real-time web searches and can scrape content from specific URLs. Returns LLM-optimized context from relevant websites. +- **context7**: Library documentation lookup. Fetches up-to-date documentation for any library to assist with accurate coding. ### Other Features diff --git a/src/index.ts b/src/index.ts index e2f53d3..8bca4c2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,7 +3,33 @@ import { builtinAgents } from "./agents" import { createTodoContinuationEnforcer, createContextWindowMonitorHook, createSessionRecoveryHook } from "./hooks" import { updateTerminalTitle } from "./features/terminal" import { builtinTools } from "./tools" -import { builtinMcps } from "./mcp" +import { createBuiltinMcps, type McpName } from "./mcp" +import * as fs from "fs" +import * as path from "path" + +interface OhMyOpenCodeConfig { + disabled_mcps?: McpName[] +} + +function loadPluginConfig(directory: string): OhMyOpenCodeConfig { + const configPaths = [ + path.join(directory, "oh-my-opencode.json"), + path.join(directory, ".oh-my-opencode.json"), + ] + + for (const configPath of configPaths) { + try { + if (fs.existsSync(configPath)) { + const content = fs.readFileSync(configPath, "utf-8") + return JSON.parse(content) as OhMyOpenCodeConfig + } + } catch { + // Ignore parse errors, use defaults + } + } + + return {} +} const OhMyOpenCodePlugin: Plugin = async (ctx) => { const todoContinuationEnforcer = createTodoContinuationEnforcer(ctx) @@ -12,6 +38,8 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => { updateTerminalTitle({ sessionId: "main" }) + const pluginConfig = loadPluginConfig(ctx.directory) + let mainSessionID: string | undefined let currentSessionID: string | undefined let currentSessionTitle: string | undefined @@ -30,7 +58,7 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => { } config.mcp = { ...config.mcp, - ...builtinMcps, + ...createBuiltinMcps(pluginConfig.disabled_mcps), } }, diff --git a/src/mcp/context7.ts b/src/mcp/context7.ts new file mode 100644 index 0000000..bc85800 --- /dev/null +++ b/src/mcp/context7.ts @@ -0,0 +1,5 @@ +export const context7 = { + type: "remote" as const, + url: "https://mcp.context7.com/mcp", + enabled: true, +} diff --git a/src/mcp/index.ts b/src/mcp/index.ts index cef2b82..951e6b9 100644 --- a/src/mcp/index.ts +++ b/src/mcp/index.ts @@ -1,5 +1,23 @@ import { websearch_exa } from "./websearch-exa" +import { context7 } from "./context7" -export const builtinMcps = { +export type McpName = "websearch_exa" | "context7" + +const allBuiltinMcps: Record = { websearch_exa, + context7, } + +export function createBuiltinMcps(disabledMcps: McpName[] = []) { + const mcps: Record = {} + + for (const [name, config] of Object.entries(allBuiltinMcps)) { + if (!disabledMcps.includes(name as McpName)) { + mcps[name] = config + } + } + + return mcps +} + +export const builtinMcps = allBuiltinMcps