anthropics / anthropics/claude-agent-sdk-typescript

AgentDefinition.tools and disallowedTools are not enforced for subagent child processes

Aperta
#172 1 commento 1 reazione 0 assegnatari Vedi su GitHub
bug
Lingua principale
Shell
Stelle
1.8k
Fork
226
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Descrizione

## Summary

`AgentDefinition.tools` and `AgentDefinition.disallowedTools` are documented as controlling which tools a subagent has access to, but they are **not enforced** when the CLI spawns subagent child processes. The subagent model still sees and can attempt to call tools that should be disallowed.

## Expected Behavior

When an agent definition specifies:
```typescript
const agents = {
products: {
description: "Check product availability",
prompt: "...",
tools: ["Read", "Write", "mcp__amazon-search__search"],
disallowedTools: ["Task"],
model: "sonnet",
}
};
```

The `products` subagent should:
1. Only see `Read`, `Write`, and `mcp__amazon-search__search` in its tool list
2. NOT see `Task` in its tool list at all
3. Be unable to call `Task`

Per the `SessionOptions.disallowedTools` JSDoc: *"These tools will be removed from the model's context and cannot be used."*

## Actual Behavior

The subagent model **still sees `Task`** in its tool list and attempts to call it. The `tools` whitelist and `disallowedTools` blacklist from `AgentDefinition` have no effect on which tools the subagent child process receives.

## Root Cause Analysis

The SDK correctly passes the `agents` config to the CLI via the `initialize` control request. The `SubagentSession` class also accepts `allowedTools` and `disallowedTools` and passes them as `--allowedTools` / `--disallowedTools` CLI flags to the child process.

However, when the CLI's internal `Task` tool handler spawns a subagent child process, it does not appear to map the `AgentDefinition.tools` → `--allowedTools` or `AgentDefinition.disallowedTools` → `--disallowedTools` CLI flags on the child process.

## Impact

This causes subagents to call `Task` recursively, spawning nested subagent chains (e.g., `products → products → products`) that crash with `"CLI output was not valid JSON"` when parent sessions end while nested subagents have pending MCP calls.

## Current Workaround

We use a `PreToolUse` hook to manually track subagent sessions and block `Task` calls:

```typescript
// Track subagent sessions via SubagentStart hook
const activeSubagentSessions = new Map();

// Block Task calls in PreToolUse hook
function createSubagentTaskBlockerHook() {
return async function(input) {
if (input.tool_name === "Task" && activeSubagentSessions.has(input.session_id)) {
return {
continue: false,
systemMessage: "FORBIDDEN: You cannot use Task...",
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "deny",
permissionDecisionReason: "Task tool is not allowed in subagents.",
},
};
}
return { continue: true };
};
}
```

This works but requires significant boilerplate that `AgentDefinition.tools`/`disallowedTools` should handle natively.

## Environment

- SDK version: 0.2.39
- Claude Code version: 2.1.39
- Runtime: Bun
- Platform: Linux (Docker) / macOS

Guida per i contributori

Nessuna guida per i contributori indicizzata per questo repository

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.