Skip to content

Commit 1ec71e4

Browse files
committed
support wildcard matching tool names in config
1 parent 5fbbdca commit 1ec71e4

4 files changed

Lines changed: 37 additions & 3 deletions

File tree

opencode.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
{
22
"$schema": "https://opencode.ai/config.json",
3+
"agent": {
4+
"build": {}
5+
},
36
"mcp": {
47
"context7": {
58
"type": "remote",

packages/opencode/src/session/index.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import { ToolRegistry } from "../tool/registry"
4242
import { Plugin } from "../plugin"
4343
import { Agent } from "../agent/agent"
4444
import { Permission } from "../permission"
45+
import { Wildcard } from "../util/wildcard"
4546

4647
export namespace Session {
4748
const log = Log.create({ service: "session" })
@@ -768,7 +769,7 @@ export namespace Session {
768769
mergeDeep(input.tools ?? {}),
769770
)
770771
for (const item of await ToolRegistry.tools(input.providerID, input.modelID)) {
771-
if (enabledTools[item.id] === false) continue
772+
if (Wildcard.all(item.id, enabledTools) === false) continue
772773
tools[item.id] = tool({
773774
id: item.id as any,
774775
description: item.description,
@@ -829,7 +830,7 @@ export namespace Session {
829830
}
830831

831832
for (const [key, item] of Object.entries(await MCP.tools())) {
832-
if (enabledTools[key] === false) continue
833+
if (Wildcard.all(key, enabledTools) === false) continue
833834
const execute = item.execute
834835
if (!execute) continue
835836
item.execute = async (args, opts) => {

packages/opencode/src/util/wildcard.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { sortBy, pipe } from "remeda"
2+
13
export namespace Wildcard {
24
export function match(str: string, pattern: string) {
35
const regex = new RegExp(
@@ -11,4 +13,16 @@ export namespace Wildcard {
1113
)
1214
return regex.test(str)
1315
}
16+
17+
export function all(input: string, patterns: Record<string, any>) {
18+
const sorted = pipe(patterns, Object.entries, sortBy([([key]) => key.length, "asc"], [([key]) => key, "asc"]))
19+
let result = undefined
20+
for (const [pattern, value] of sorted) {
21+
if (match(input, pattern)) {
22+
result = value
23+
continue
24+
}
25+
}
26+
return result
27+
}
1428
}

packages/web/src/content/docs/docs/agents.mdx

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,22 @@ Control which tools are available in this agent with the `tools` config. You can
318318
}
319319
```
320320

321+
You can also use wildcards to control multiple tools at once. For example, to disable all tools from an MCP server:
322+
323+
```json title="opencode.json"
324+
{
325+
"agent": {
326+
"readonly": {
327+
"tools": {
328+
"mymcp_*": false,
329+
"write": false,
330+
"edit": false
331+
}
332+
}
333+
}
334+
}
335+
```
336+
321337
If no tools are specified, all tools are enabled by default.
322338

323339
---
@@ -371,7 +387,7 @@ For example, with OpenAI's reasoning models, you can control the reasoning effor
371387
"agent": {
372388
"deep-thinker": {
373389
"description": "Agent that uses high reasoning effort for complex problems",
374-
"model": "openai/gpt-5-turbo",
390+
"model": "openai/gpt-5-turbo",
375391
"reasoningEffort": "high",
376392
"textVerbosity": "low"
377393
}

0 commit comments

Comments
 (0)