From 82944f83e60c9f6df1df6db4887cb0c5c85da39c Mon Sep 17 00:00:00 2001 From: Miles Date: Sun, 26 Apr 2026 21:02:28 +0800 Subject: [PATCH 1/6] fix(opencode): agent create generates permissions field with deny instead of deprecated tools field --- packages/opencode/src/cli/cmd/agent.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/opencode/src/cli/cmd/agent.ts b/packages/opencode/src/cli/cmd/agent.ts index acad3866818f..7f058d248383 100644 --- a/packages/opencode/src/cli/cmd/agent.ts +++ b/packages/opencode/src/cli/cmd/agent.ts @@ -167,11 +167,11 @@ const AgentCreateCommand = cmd({ mode = modeResult } - // Build tools config - const tools: Record = {} + // Build permissions config + const permissions: Record = {} for (const tool of AVAILABLE_TOOLS) { if (!selectedTools.includes(tool)) { - tools[tool] = false + permissions[tool] = "deny" } } @@ -179,13 +179,13 @@ const AgentCreateCommand = cmd({ const frontmatter: { description: string mode: AgentMode - tools?: Record + permissions?: Record } = { description: generated.whenToUse, mode, } - if (Object.keys(tools).length > 0) { - frontmatter.tools = tools + if (Object.keys(permissions).length > 0) { + frontmatter.permissions = permissions } // Write file From a29a78c49c472283e7047d62191da681f77a8653 Mon Sep 17 00:00:00 2001 From: Aiden Cline <63023139+rekram1-node@users.noreply.github.com> Date: Sun, 26 Apr 2026 22:41:52 -0500 Subject: [PATCH 2/6] Change permissions key to singular in frontmatter --- packages/opencode/src/cli/cmd/agent.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/opencode/src/cli/cmd/agent.ts b/packages/opencode/src/cli/cmd/agent.ts index 7f058d248383..7c3b9d1f52d8 100644 --- a/packages/opencode/src/cli/cmd/agent.ts +++ b/packages/opencode/src/cli/cmd/agent.ts @@ -185,7 +185,7 @@ const AgentCreateCommand = cmd({ mode, } if (Object.keys(permissions).length > 0) { - frontmatter.permissions = permissions + frontmatter.permission = permissions } // Write file From 5d13e3a9ebbd62a6469aa6f09abec55876ee0024 Mon Sep 17 00:00:00 2001 From: Aiden Cline <63023139+rekram1-node@users.noreply.github.com> Date: Sun, 26 Apr 2026 22:44:15 -0500 Subject: [PATCH 3/6] Rename permissions to permission in agent.ts --- packages/opencode/src/cli/cmd/agent.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/opencode/src/cli/cmd/agent.ts b/packages/opencode/src/cli/cmd/agent.ts index 7c3b9d1f52d8..4685a786bd19 100644 --- a/packages/opencode/src/cli/cmd/agent.ts +++ b/packages/opencode/src/cli/cmd/agent.ts @@ -179,7 +179,7 @@ const AgentCreateCommand = cmd({ const frontmatter: { description: string mode: AgentMode - permissions?: Record + permission?: Record } = { description: generated.whenToUse, mode, From 8d604bd723d5cf8ae60bfcbfd18a76cb3796f59d Mon Sep 17 00:00:00 2001 From: Aiden Cline Date: Sun, 26 Apr 2026 23:31:43 -0500 Subject: [PATCH 4/6] fixes and docs updates --- packages/opencode/src/cli/cmd/agent.ts | 42 ++++++++------- packages/web/src/content/docs/agents.mdx | 66 ++++++++++++++++-------- packages/web/src/content/docs/cli.mdx | 14 ++++- 3 files changed, 80 insertions(+), 42 deletions(-) diff --git a/packages/opencode/src/cli/cmd/agent.ts b/packages/opencode/src/cli/cmd/agent.ts index 4685a786bd19..f714fbf7c962 100644 --- a/packages/opencode/src/cli/cmd/agent.ts +++ b/packages/opencode/src/cli/cmd/agent.ts @@ -15,7 +15,10 @@ import type { Argv } from "yargs" type AgentMode = "all" | "primary" | "subagent" -const AVAILABLE_TOOLS = ["bash", "read", "write", "edit", "glob", "grep", "webfetch", "task", "todowrite"] +// Permission keys (not raw tool names). Multiple tools can map to a single +// permission — e.g. write/edit/apply_patch all gate on `edit` — so we configure +// agents at the permission level to match how the runtime actually enforces it. +const AVAILABLE_PERMISSIONS = ["bash", "read", "edit", "glob", "grep", "webfetch", "task", "todowrite"] const AgentCreateCommand = cmd({ command: "create", @@ -35,9 +38,10 @@ const AgentCreateCommand = cmd({ describe: "agent mode", choices: ["all", "primary", "subagent"] as const, }) - .option("tools", { + .option("permissions", { type: "string", - describe: `comma-separated list of tools to enable (default: all). Available: "${AVAILABLE_TOOLS.join(", ")}"`, + alias: ["tools"], + describe: `comma-separated list of permissions to allow (default: all). Available: "${AVAILABLE_PERMISSIONS.join(", ")}"`, }) .option("model", { type: "string", @@ -51,9 +55,9 @@ const AgentCreateCommand = cmd({ const cliPath = args.path const cliDescription = args.description const cliMode = args.mode as AgentMode | undefined - const cliTools = args.tools + const perms = args.permissions - const isFullyNonInteractive = cliPath && cliDescription && cliMode && cliTools !== undefined + const isFullyNonInteractive = cliPath && cliDescription && cliMode && perms !== undefined if (!isFullyNonInteractive) { UI.empty() @@ -120,21 +124,21 @@ const AgentCreateCommand = cmd({ }) spinner.stop(`Agent ${generated.identifier} generated`) - // Select tools - let selectedTools: string[] - if (cliTools !== undefined) { - selectedTools = cliTools ? cliTools.split(",").map((t) => t.trim()) : AVAILABLE_TOOLS + // Select permissions to allow + let selected: string[] + if (perms !== undefined) { + selected = perms ? perms.split(",").map((t) => t.trim()) : AVAILABLE_PERMISSIONS } else { const result = await prompts.multiselect({ - message: "Select tools to enable (Space to toggle)", - options: AVAILABLE_TOOLS.map((tool) => ({ - label: tool, - value: tool, + message: "Select permissions to allow (Space to toggle)", + options: AVAILABLE_PERMISSIONS.map((permission) => ({ + label: permission, + value: permission, })), - initialValues: AVAILABLE_TOOLS, + initialValues: AVAILABLE_PERMISSIONS, }) if (prompts.isCancel(result)) throw new UI.CancelledError() - selectedTools = result + selected = result } // Get mode @@ -167,11 +171,11 @@ const AgentCreateCommand = cmd({ mode = modeResult } - // Build permissions config + // Build permissions config — deny anything not explicitly selected. const permissions: Record = {} - for (const tool of AVAILABLE_TOOLS) { - if (!selectedTools.includes(tool)) { - permissions[tool] = "deny" + for (const permission of AVAILABLE_PERMISSIONS) { + if (!selected.includes(permission)) { + permissions[permission] = "deny" } } diff --git a/packages/web/src/content/docs/agents.mdx b/packages/web/src/content/docs/agents.mdx index 5522f77aae61..47a3effd082b 100644 --- a/packages/web/src/content/docs/agents.mdx +++ b/packages/web/src/content/docs/agents.mdx @@ -149,19 +149,17 @@ Configure agents in your `opencode.json` config file: "mode": "primary", "model": "anthropic/claude-sonnet-4-20250514", "prompt": "{file:./prompts/build.txt}", - "tools": { - "write": true, - "edit": true, - "bash": true + "permission": { + "edit": "allow", + "bash": "allow" } }, "plan": { "mode": "primary", "model": "anthropic/claude-haiku-4-20250514", - "tools": { - "write": false, - "edit": false, - "bash": false + "permission": { + "edit": "deny", + "bash": "deny" } }, "code-reviewer": { @@ -169,9 +167,8 @@ Configure agents in your `opencode.json` config file: "mode": "subagent", "model": "anthropic/claude-sonnet-4-20250514", "prompt": "You are a code reviewer. Focus on security, performance, and maintainability.", - "tools": { - "write": false, - "edit": false + "permission": { + "edit": "deny" } } } @@ -193,10 +190,9 @@ description: Reviews code for quality and best practices mode: subagent model: anthropic/claude-sonnet-4-20250514 temperature: 0.1 -tools: - write: false - edit: false - bash: false +permission: + edit: deny + bash: deny --- You are in code review mode. Focus on: @@ -417,12 +413,39 @@ You can also use wildcards in legacy `tools` entries to control multiple tools a ### Permissions -You can configure permissions to manage what actions an agent can take. Currently, the permissions for the `edit`, `bash`, and `webfetch` tools can be configured to: +You can configure permissions to manage what actions an agent can take. Each permission key can be set to: - `"ask"` — Prompt for approval before running the tool - `"allow"` — Allow all operations without approval - `"deny"` — Disable the tool +The available permission keys are: + +| Key | Tools it gates | +| -------------------- | ----------------------------------------------------------------------------- | +| `read` | `read` | +| `edit` | `write`, `edit`, `apply_patch` | +| `glob` | `glob` | +| `grep` | `grep` | +| `list` | `list` | +| `bash` | `bash` | +| `task` | `task` | +| `external_directory` | Any tool that reads or writes files outside the project worktree | +| `todowrite` | `todowrite`, `todoread` | +| `webfetch` | `webfetch` | +| `websearch` | `websearch` | +| `codesearch` | `codesearch` | +| `lsp` | `lsp` | +| `skill` | `skill` | +| `question` | `question` | +| `doom_loop` | Recovery prompts when an agent appears stuck | + +`read`, `edit`, `glob`, `grep`, `list`, `bash`, `task`, `external_directory`, `lsp`, and `skill` accept either a shorthand action (`"allow" | "ask" | "deny"`) or an object of glob/pattern → action for fine-grained control. The remaining keys accept the shorthand action only. + +:::note +Permission keys are matched as wildcard patterns against the underlying tool name, so the same syntax works for built-ins, custom tools, and MCP tools — for example `"mymcp_*": "deny"` denies every tool from an MCP server, and `"mymcp_search": "ask"` targets a single one. +::: + ```json title="opencode.json" { "$schema": "https://opencode.ai/config.json", @@ -680,7 +703,7 @@ This interactive command will: 1. Ask where to save the agent; global or project-specific. 2. Description of what the agent should do. 3. Generate an appropriate system prompt and identifier. -4. Let you select which tools the agent can access. +4. Let you select which permissions the agent should be allowed (anything you don't select is denied). 5. Finally, create a markdown file with the agent configuration. --- @@ -713,8 +736,8 @@ Do you have an agent you'd like to share? [Submit a PR](https://github.com/anoma --- description: Writes and maintains project documentation mode: subagent -tools: - bash: false +permission: + bash: deny --- You are a technical writer. Create clear, comprehensive documentation. @@ -735,9 +758,8 @@ Focus on: --- description: Performs security audits and identifies vulnerabilities mode: subagent -tools: - write: false - edit: false +permission: + edit: deny --- You are a security expert. Focus on identifying potential security issues. diff --git a/packages/web/src/content/docs/cli.mdx b/packages/web/src/content/docs/cli.mdx index fb1130fe50c5..7e235e259f18 100644 --- a/packages/web/src/content/docs/cli.mdx +++ b/packages/web/src/content/docs/cli.mdx @@ -93,7 +93,19 @@ Create a new agent with custom configuration. opencode agent create ``` -This command will guide you through creating a new agent with a custom system prompt and tool configuration. +This command will guide you through creating a new agent with a custom system prompt and permission configuration. Anything you don't allow is denied in the generated agent's frontmatter. + +#### Flags + +| Flag | Description | +| ---------------- | ---------------------------------------------------------------------------------------------------------- | +| `--path` | Directory to write the agent file to (defaults to global or `.opencode/agent` based on the prompt) | +| `--description` | What the agent should do | +| `--mode` | Agent mode: `all`, `primary`, or `subagent` | +| `--permissions` | Comma-separated list of permissions to allow (default: all). Available: `bash`, `read`, `edit`, `glob`, `grep`, `webfetch`, `task`, `todowrite`. Anything omitted is denied. Alias: `--tools` | +| `--model`, `-m` | Model to use, in `provider/model` format | + +Passing all of `--path`, `--description`, `--mode`, and `--permissions` runs the command non-interactively. --- From 2f8b1eb4bfa9fdd157f575ace765d59d504c98f4 Mon Sep 17 00:00:00 2001 From: yepeng Date: Mon, 27 Apr 2026 12:39:52 +0800 Subject: [PATCH 5/6] fix: add missing permission keys to AVAILABLE_PERMISSIONS --- packages/opencode/src/cli/cmd/agent.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/opencode/src/cli/cmd/agent.ts b/packages/opencode/src/cli/cmd/agent.ts index f714fbf7c962..f174c49d06a4 100644 --- a/packages/opencode/src/cli/cmd/agent.ts +++ b/packages/opencode/src/cli/cmd/agent.ts @@ -18,7 +18,7 @@ type AgentMode = "all" | "primary" | "subagent" // Permission keys (not raw tool names). Multiple tools can map to a single // permission — e.g. write/edit/apply_patch all gate on `edit` — so we configure // agents at the permission level to match how the runtime actually enforces it. -const AVAILABLE_PERMISSIONS = ["bash", "read", "edit", "glob", "grep", "webfetch", "task", "todowrite"] +const AVAILABLE_PERMISSIONS = ["bash", "read", "edit", "glob", "grep", "webfetch", "task", "todowrite", "websearch", "codesearch", "lsp", "skill"] const AgentCreateCommand = cmd({ command: "create", From eef8948910db11c33880d8f29e2629baf04159ad Mon Sep 17 00:00:00 2001 From: Aiden Cline <63023139+rekram1-node@users.noreply.github.com> Date: Mon, 27 Apr 2026 00:13:26 -0500 Subject: [PATCH 6/6] Update permissions list in CLI documentation Added new permissions: websearch, codesearch, lsp, and skill. --- packages/web/src/content/docs/cli.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web/src/content/docs/cli.mdx b/packages/web/src/content/docs/cli.mdx index 7e235e259f18..2fad7c2b603f 100644 --- a/packages/web/src/content/docs/cli.mdx +++ b/packages/web/src/content/docs/cli.mdx @@ -102,7 +102,7 @@ This command will guide you through creating a new agent with a custom system pr | `--path` | Directory to write the agent file to (defaults to global or `.opencode/agent` based on the prompt) | | `--description` | What the agent should do | | `--mode` | Agent mode: `all`, `primary`, or `subagent` | -| `--permissions` | Comma-separated list of permissions to allow (default: all). Available: `bash`, `read`, `edit`, `glob`, `grep`, `webfetch`, `task`, `todowrite`. Anything omitted is denied. Alias: `--tools` | +| `--permissions` | Comma-separated list of permissions to allow (default: all). Available: `bash`, `read`, `edit`, `glob`, `grep`, `webfetch`, `task`, `todowrite`, `websearch`, `codesearch`, `lsp`, `skill`. Anything omitted is denied. Alias: `--tools` | | `--model`, `-m` | Model to use, in `provider/model` format | Passing all of `--path`, `--description`, `--mode`, and `--permissions` runs the command non-interactively.