diff --git a/opencode.json b/opencode.json index 59f14ac7..003253ee 100644 --- a/opencode.json +++ b/opencode.json @@ -1,5 +1,8 @@ { "$schema": "https://opencode.ai/config.json", + "agent": { + "build": {} + }, "mcp": { "context7": { "type": "remote", diff --git a/packages/opencode/src/session/index.ts b/packages/opencode/src/session/index.ts index 5f7bf000..6d2b9486 100644 --- a/packages/opencode/src/session/index.ts +++ b/packages/opencode/src/session/index.ts @@ -42,6 +42,7 @@ import { ToolRegistry } from "../tool/registry" import { Plugin } from "../plugin" import { Agent } from "../agent/agent" import { Permission } from "../permission" +import { Wildcard } from "../util/wildcard" export namespace Session { const log = Log.create({ service: "session" }) @@ -768,7 +769,7 @@ export namespace Session { mergeDeep(input.tools ?? {}), ) for (const item of await ToolRegistry.tools(input.providerID, input.modelID)) { - if (enabledTools[item.id] === false) continue + if (Wildcard.all(item.id, enabledTools) === false) continue tools[item.id] = tool({ id: item.id as any, description: item.description, @@ -829,7 +830,7 @@ export namespace Session { } for (const [key, item] of Object.entries(await MCP.tools())) { - if (enabledTools[key] === false) continue + if (Wildcard.all(key, enabledTools) === false) continue const execute = item.execute if (!execute) continue item.execute = async (args, opts) => { diff --git a/packages/opencode/src/util/wildcard.ts b/packages/opencode/src/util/wildcard.ts index 43fc417d..d329501f 100644 --- a/packages/opencode/src/util/wildcard.ts +++ b/packages/opencode/src/util/wildcard.ts @@ -1,3 +1,5 @@ +import { sortBy, pipe } from "remeda" + export namespace Wildcard { export function match(str: string, pattern: string) { const regex = new RegExp( @@ -11,4 +13,16 @@ export namespace Wildcard { ) return regex.test(str) } + + export function all(input: string, patterns: Record) { + const sorted = pipe(patterns, Object.entries, sortBy([([key]) => key.length, "asc"], [([key]) => key, "asc"])) + let result = undefined + for (const [pattern, value] of sorted) { + if (match(input, pattern)) { + result = value + continue + } + } + return result + } } diff --git a/packages/web/src/content/docs/docs/agents.mdx b/packages/web/src/content/docs/docs/agents.mdx index 80e1867d..bcb0eca2 100644 --- a/packages/web/src/content/docs/docs/agents.mdx +++ b/packages/web/src/content/docs/docs/agents.mdx @@ -318,6 +318,22 @@ Control which tools are available in this agent with the `tools` config. You can } ``` +You can also use wildcards to control multiple tools at once. For example, to disable all tools from an MCP server: + +```json title="opencode.json" +{ + "agent": { + "readonly": { + "tools": { + "mymcp_*": false, + "write": false, + "edit": false + } + } + } +} +``` + If no tools are specified, all tools are enabled by default. --- @@ -371,7 +387,7 @@ For example, with OpenAI's reasoning models, you can control the reasoning effor "agent": { "deep-thinker": { "description": "Agent that uses high reasoning effort for complex problems", - "model": "openai/gpt-5-turbo", + "model": "openai/gpt-5-turbo", "reasoningEffort": "high", "textVerbosity": "low" }