Skip to content

fix(opencode): inherit MCP tool allow permissions in subagent sessions#30288

Open
ollikurki wants to merge 1 commit into
anomalyco:devfrom
ollikurki:fix/subagent-mcp-permission-inheritance
Open

fix(opencode): inherit MCP tool allow permissions in subagent sessions#30288
ollikurki wants to merge 1 commit into
anomalyco:devfrom
ollikurki:fix/subagent-mcp-permission-inheritance

Conversation

@ollikurki
Copy link
Copy Markdown

@ollikurki ollikurki commented Jun 1, 2026

Issue for this PR

Closes #16491, #3808

Type of change

  • Bug fix

What does this PR do?

Subagents spawned via the Task tool can see MCP tools in their tool registry but get permission denied when trying to execute them. The root cause is that deriveSubagentSessionPermission() only forwards deny rules and external_directory rules from the parent session — never the allow rules that MCP tools require.

MCP tool permission keys follow the pattern sanitize(clientName) + "_" + sanitize(toolName) (e.g. context7_resolve-library-id, matrix_matrix_read). This fix copies all allow rules whose permission key contains an underscore, which covers MCP tools while leaving native opencode tools (todowrite, task, bash, edit, etc.) unaffected since they don't contain underscores in their names. Wildcard * allow rules are also forwarded.

In deriveSubagentSessionPermission() (packages/opencode/src/agent/subagent-permissions.ts), a new filter extracts MCP-allow rules:

const parentSessionMcpAllows = input.parentSessionPermission.filter(
  (rule) => rule.action === "allow" && (rule.permission.includes("_") || rule.permission === "*"),
)

These are then spread into the returned ruleset alongside the existing deny, external_directory, and task/todowrite defaults. The approach is:

  1. Minimal: only MCP-relevant allow rules are forwarded, not all allow rules
  2. No coupling to MCP internals: no need to import MCP service or enumerate MCP tool names at spawn time
  3. Works with all MCP servers: any MCP server automatically works because the underscore pattern is universal
  4. Wildcards supported: * allow rules are also forwarded for full-permission parent sessions

How did you verify your code works?

Added 4 new test cases to packages/opencode/test/agent/plan-mode-subagent-bypass.test.ts:

  1. MCP allow rules are inherited: Subagent can execute MCP tools (myserver_tool-one, otherclient_resource-list) after parent approved them
  2. Wildcard allow is inherited: Subagent receives * allow rules from parent
  3. Native tool allows don't leak: bash: allow in parent does NOT propagate through the underscore filter — evaluates to "ask" (default), not "allow"
  4. MCP allow rules coexist with deny rules: Parent can allow MCP tools and deny edit simultaneously — subagent inherits both

All 8 tests pass (4 existing + 4 new):

bun test test/agent/plan-mode-subagent-bypass.test.ts
  8 pass
  0 fail
  25 expect() calls

Screenshots / recordings

N/A — no UI changes, purely a permission logic fix.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

Subagents spawned via the Task tool could see MCP tools in their tool
registry but got permission denied when trying to execute them. The root
cause was that deriveSubagentSessionPermission only forwarded deny rules
and external_directory rules from the parent session, never copying the
allow rules that MCP tools require.

MCP tool permission keys contain underscores (e.g. context7_resolve-library-id,
matrix_matrix_read) as they follow the sanitize(clientName) + '_' + sanitize(toolName)
naming pattern. This fix copies all allow rules whose permission key
contains an underscore, which covers MCP tools while leaving native tools
(todowrite, task, bash, edit, etc.) unaffected since they don't contain
underscores in their permission names. Wildcard '*' allow rules are also
forwarded.

Co-authored-by: Olli Kurki <kurki.olli@outlook.com>
Co-authored-by: AI <ai@opencode.ai>
@github-actions github-actions Bot added the needs:compliance This means the issue will auto-close after 2 hours. label Jun 1, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 1, 2026

The following comment was made by an LLM, it may be inaccurate:

Based on my search results, I found one potential duplicate:

PR #30085 - fix(opencode): grant MCP tool permissions in subagent sessions
#30085

This PR appears to be addressing the exact same issue as the current PR (#30288). Both PRs are focused on granting/inheriting MCP tool permissions in subagent sessions, which are the issues closed by #16491 and #3808. You should verify whether PR #30085 is open and compare its implementation approach with PR #30288 to determine if one should be closed in favor of the other.

@github-actions github-actions Bot removed the needs:compliance This means the issue will auto-close after 2 hours. label Jun 1, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 1, 2026

Thanks for updating your PR! It now meets our contributing guidelines. 👍

@ollikurki
Copy link
Copy Markdown
Author

For context: there are other open PRs addressing #16491 (#30085) that take a different approach — they import the MCP service into task.ts and enumerate tool names at spawn time. This PR takes a lighter approach: pattern-based filtering in subagent-permissions.ts that doesn't require importing MCP internals. Both approaches solve the same problem; ours is just more narrowly scoped to MCP tool permission inheritance without coupling to the MCP service layer.

@ZK-Andy
Copy link
Copy Markdown

ZK-Andy commented Jun 2, 2026

After comparing #30085 and #30288, #30288 is clearly the better fix. It inherits parent session permissions cleanly, respects the existing allow/deny model, and follows least privilege—unlike #30085 which hard‑codes full MCP access. Go with #30288.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Subagents spawned via Task tool cannot execute MCP tools despite appearing in tool registry

2 participants