microsoft / microsoft/conductor
claude-agent-sdk: honoring the per-agent tools: allowlist needs a permission-mode redesign, not a name mapping
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 451
- Forks
- 65
- Avg merge
- 1d 18h
- Merged PRs (30d)
- 39
Description
Summary
ClaudeAgentSdkProvider declares workflow_tools_passthrough=False, so config/validator.py rejects any non-empty per-agent tools: list and _resolve_tool_config refuses one at execute time. #335 wired up MCP servers but deliberately left this carve-out in place, because closing it is not the name-mapping exercise it first appears to be.
Why it isn't just a name mapping
The obvious idea is to translate Conductor's <server>__<tool> names (mcp/manager.py:197, documented at docs/mcp-tools.md:150) into the CLI's mcp__<server>__<tool> and pass them as allowed_tools. Three things break that:
-
allowed_toolsis not an availability filter. Per the SDK's own docstrings (types.py:1581-1600),toolsselects the built-in tool set,allowed_toolsis a permission auto-approve list, anddisallowed_toolsis the only field that removes a tool from the model's context. Putting an allowlist inallowed_toolsdoes not prevent anything from being called. -
permission_mode="bypassPermissions"makes it a no-op anyway. That is what the provider sets today on the default path (granting theclaude_codepreset without prompting). UnderbypassPermissionsevery tool is auto-approved regardless ofallowed_tools, so an allowlist would be silently ignored — exactly the "silently granting different tools than declared is a security regression" failure the current refusal exists to prevent. -
Only MCP-shaped names are translatable at all. A workflow-level
tools:entry can be an arbitrary name (e.g.web_searchinexamples/research-assistant.yaml:54) with no corresponding CLI tool ID. So even a correct mapping would only ever cover part of the allowlist, makingworkflow_tools_passthrough=Truea partial truth in a boolean descriptor — which AGENTS.md explicitly forbids ("lying in the descriptor undermines the framework").
Possible directions
permission_mode="dontAsk"+allowed_tools— non-approved tools are denied, but they stay visible in the model's context, so the model can waste turns attempting them. Also changes default behavior for existing users.- A
can_use_toolcallback (ClaudeAgentOptions.can_use_tool) — the most precise enforcement point, and the only one that can deny per call with a reason. disallowed_tools— needs the full tool list up front, which requires an MCP handshake Conductor does not perform for this provider.
Any of these needs a decision about what happens to non-MCP-shaped names, and whether the descriptor needs to become finer-grained than a single boolean.
Related
- #335 / #346 — MCP server support (left this carve-out explicitly out of scope)
docs/providers/experimental.md— promotion criterion 1 requires no carve-outs in active use
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with config/validator.py, the ClaudeAgentSdkProvider implementation, mcp/manager.py, and the SDK semantics in types.py:1581-1600; compare them with AGENTS.md and the provider promotion criteria in docs/providers/experimental.md. Done means a decided permission model that enforces per-agent tools safely, defines behavior for non-MCP names, and accurately represents support in the provider descriptor.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- cli, security
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100