From 89b5f49caf4ada5f0794a2ce72232701a8c32a32 Mon Sep 17 00:00:00 2001 From: leonyvon Date: Thu, 28 May 2026 18:08:11 +0800 Subject: [PATCH] fix(subagent): inherit parent session allow rules for MCP tool permissions Subagents spawned via the Task tool could see MCP tools in their registry but could not execute them. The root cause was in deriveSubagentSessionPermission: it only forwarded 'deny' and 'external_directory' rules from the parent session, dropping all 'allow' rules. This caused the permission check in session/tools.ts to evaluate MCP tool calls (which use patterns=['*']) against a ruleset with no matching allow rules, resulting in a blocked 'needsAsk' state with no interactive user to respond. Fix: forward the parent session's full permission ruleset (both deny and allow) instead of filtering. Deny rules still constrain, but previously-granted MCP tool permissions and other allowances are now properly inherited. Fixes #16491 --- packages/opencode/src/agent/subagent-permissions.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/opencode/src/agent/subagent-permissions.ts b/packages/opencode/src/agent/subagent-permissions.ts index 051f42e37bb3..bde5a70dd5d4 100644 --- a/packages/opencode/src/agent/subagent-permissions.ts +++ b/packages/opencode/src/agent/subagent-permissions.ts @@ -9,8 +9,9 @@ import type { Agent } from "./agent" * restriction lives on the agent ruleset, not on the session, so a * subagent that only inherited the parent SESSION's permission would * silently bypass it. (#26514) - * 2. The parent **session's** deny rules and external_directory rules — - * same forwarding the original code already did. + * 2. The parent **session's** full permission ruleset — includes both deny + * and allow rules, so that previously-granted MCP tool permissions + * and other allowances are inherited by the subagent. (#16491) * 3. Default `todowrite` and `task` denies if the subagent's own ruleset * doesn't already permit them. */ @@ -25,9 +26,7 @@ export function deriveSubagentSessionPermission(input: { input.parentAgent?.permission.filter((rule) => rule.action === "deny" && rule.permission === "edit") ?? [] return [ ...parentAgentDenies, - ...input.parentSessionPermission.filter( - (rule) => rule.permission === "external_directory" || rule.action === "deny", - ), + ...input.parentSessionPermission, ...(canTodo ? [] : [{ permission: "todowrite" as const, pattern: "*" as const, action: "deny" as const }]), ...(canTask ? [] : [{ permission: "task" as const, pattern: "*" as const, action: "deny" as const }]), ]