summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--opencode.json3
-rw-r--r--packages/opencode/src/session/index.ts5
-rw-r--r--packages/opencode/src/util/wildcard.ts14
-rw-r--r--packages/web/src/content/docs/docs/agents.mdx18
4 files changed, 37 insertions, 3 deletions
diff --git a/opencode.json b/opencode.json
index 59f14ac75..003253ee7 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 5f7bf000d..6d2b94863 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 43fc417da..d329501f2 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<string, any>) {
+ 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 80e1867d7..bcb0eca2a 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"
}