Agent commands. Your AI agent uses this node in workflows. You don’t configure it directly.
Experimental. This node is not extensively tested and may have unexpected behavior. Use with caution in production workflows.
The claude-code node runs agentic tasks using Claude Code’s capabilities. It can read files, write content, execute shell commands, and iterate on complex problems - useful for development, research, analysis, or any task needing file access and multi-step reasoning.
This node requires Claude Code CLI authentication or an Anthropic API key.
Parameters
Prompt parameters
| Parameter | Type | Required | Default | Description |
|---|
prompt | str | Yes | - | The prompt to send to Claude (max 10,000 chars) |
output_schema | dict | No | - | JSON Schema for structured output |
Execution parameters
| Parameter | Type | Required | Default | Description |
|---|
cwd | str | No | Current dir | Working directory for Claude |
model | str | No | claude-sonnet-4-5 | Claude model to use |
allowed_tools | list | No | All tools | Permitted tools |
disallowed_tools | list | No | - | Tools or patterns to deny |
max_turns | int | No | 50 | Maximum conversation turns (1-100; must be at least 2 with output_schema) |
max_thinking_tokens | int | No | 8000 | Reasoning budget (1000-100000) |
timeout | int | No | 300 | Execution timeout in seconds (30-3600) |
system_prompt | str | No | - | Custom system instructions |
resume | str | No | - | Session ID to resume a previous conversation |
schema_retries | int | No | 1 | Schema retry attempts (0-5) when output_schema is used. 0 disables self-heal, 1 allows one corrective pass |
sandbox | dict | No | - | Sandbox configuration for command isolation |
use_api_key | bool | No | false | Bill to ANTHROPIC_API_KEY (Anthropic Console). Default uses your Claude Pro/Max subscription |
Sandbox configuration
The sandbox parameter controls command execution isolation. See the Claude Agent SDK sandbox documentation for full details.
| Key | Type | Description |
|---|
enabled | bool | Enable sandbox mode |
autoAllowBashIfSandboxed | bool | Auto-allow bash when sandboxed |
excludedCommands | list | Commands that bypass sandbox (e.g., ["docker"]) |
allowUnsandboxedCommands | bool | Allow model to request unsandboxed execution |
network | dict | Network settings (allowLocalBinding, allowUnixSockets) |
Output
| Key | Type | Description |
|---|
result | str/dict | Free-form text, parsed structured output when output_schema succeeds, or raw text on soft schema failure |
llm_usage | dict | Token usage and execution metadata (same base format as LLM node, plus Claude-specific fields) |
_schema_error | str | Soft-failure message for structured-output mode — set when structured output was unavailable, the SDK reported an error alongside the output, or the schema reference resolved to None |
Soft-failures also emit a root-level shared["__warnings__"][node_id] entry so workflow status becomes DEGRADED. This is an execution diagnostic channel, not a template output under the node.
The node always returns default from post() — schema soft-failures and SDK soft-errors do NOT route through - on-error: edges. Read ${node._schema_error} or check workflow DEGRADED status if downstream logic needs to react.
llm_usage structure
{
"model": "claude-sonnet-4-5",
"input_tokens": 21500,
"uncached_input_tokens": 1500,
"output_tokens": 450,
"total_tokens": 21950,
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 20000,
"input_token_accounting": "split_cache_fields",
"cost_usd": 0.0234,
"duration_ms": 3450,
"num_turns": 2,
"session_id": "abc123",
"retries": [
{
"input_tokens": 500,
"uncached_input_tokens": 400,
"output_tokens": 150,
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 100,
"input_token_accounting": "split_cache_fields",
"cost_usd": 0.0078,
"duration_ms": 1200,
"num_turns": 1,
"session_id": "abc123",
"model": "claude-sonnet-4-5"
}
]
}
input_tokens is the cache-inclusive total — it includes cache_creation_input_tokens and cache_read_input_tokens. uncached_input_tokens is the slice that wasn’t served from cache. In the example above, 20,000 of the 21,500 input tokens were read from cache, leaving 1,500 uncached.
cost_usd is the SDK-reported API-equivalent estimated cost. Actual billing depends on auth method; Claude Pro/Max subscription runs may report an API-equivalent cost without a direct per-call charge.
The retries field (optional) contains an array of usage records for superseded schema retry attempts. The top-level llm_usage fields reflect the final (successful) attempt only — the superseded attempts live in retries[]. The run’s reported cost and token totals (the cost summary and the execution trace) aggregate the main call and all retries; the per-node llm_usage you read via ${node.llm_usage} does not.
Authentication
By default the claude-code node uses your Claude Pro/Max subscription and blanks ANTHROPIC_API_KEY for the Claude subprocess — so an ambient key (including one stored with pflow settings set-env for the llm node) never silently bills your Anthropic Console per token. Set use_api_key: true on the node to opt into Console billing.
Subscription (default)
API key (opt in)
Install and authenticate the Claude Code CLI:npm install -g @anthropic-ai/claude-code
claude auth login # or: claude setup-token (non-interactive/CI)
Uses your Claude Pro/Max subscription with no per-token charges. Check status any time with claude auth status. Set use_api_key: true on the node, with ANTHROPIC_API_KEY available in the environment:### agent
- type: claude-code
- prompt: Refactor this module
- use_api_key: true
pflow settings set-env ANTHROPIC_API_KEY "sk-ant-..."
Bills to your Anthropic Console account (pay per token). Useful for CI/CD or when you have no subscription.
Structured output
Use output_schema to get structured responses through the Claude Agent SDK’s native JSON Schema mode. The top-level schema must declare type: object because the Claude API rejects any tool input schema without it — including top-level oneOf/anyOf/allOf/enum combinators. For array, primitive, or combinator-only outputs, wrap them inside an object property. Combinators nested inside a type: object schema work normally.
### review
Review code for security issues and return structured results.
- type: claude-code
- prompt: Review this code for security issues: ${code.content}
```yaml output_schema
type: object
properties:
risk_level:
type: string
enum: [high, medium, low]
description: Risk level
issues:
type: array
items:
type: string
description: List of security issues found
score:
type: integer
minimum: 1
maximum: 10
description: Security score
required: [risk_level, issues, score]
```
The SDK returns parsed structured output, available as a dict:
${review.result.risk_level} -> "medium"
${review.result.issues} -> ["SQL injection risk", "Missing input validation"]
${review.result.score} -> 6
If the schema is set but the SDK returns no structured output, pflow preserves the raw text in ${node.result}, writes ${node._schema_error}, and emits shared["__warnings__"][node_id] so JSON execution output reports workflow status as DEGRADED.
Warning kinds distinguish model/schema misses from SDK error signals: claude_code.schema_not_satisfied means the model did not produce matching structured output; claude_code.sdk_error_no_structured_output means the Claude CLI reported an error and no structured output was usable.
Schema self-healing
When using output_schema, the node automatically recovers from schema soft-failures through two mechanisms:
-
Scalar type coercion — If the agent returns a structurally-valid response but a scalar field has the wrong type (e.g.,
"false" string instead of false boolean), pflow coerces it to the declared type using canonical conversions:
- Boolean:
"true"/"false" (case-insensitive) → True/False
- Integer/Number: Numeric strings (
"3", "3.14") → int/float
- String: Non-string scalars →
str()
-
Resume retry — If the agent produces no structured output, returns uncoercible values, or returns a value outside a declared
enum/const, pflow asks the same session to re-emit the output with an explicit schema prompt. The schema_retries parameter (default 1) controls how many corrective attempts to make.
Conformance is judged on top-level scalar types plus enum/const constraints; an object schema without declared properties is treated as unconstrained (any object conforms).
Cost tracking includes retry attempts — the llm_usage structure aggregates tokens/cost across the main call and all retries, and --report shows the retry count per node.
Set schema_retries: 0 to disable both mechanisms (schema soft-failures immediately fall through to raw text + warning, matching pre-v0.13 behavior).
Examples
Code generation
### generate
Write a Python function to calculate Fibonacci numbers.
- type: claude-code
- prompt: Write a Python function to calculate Fibonacci numbers
- max_turns: 2
Code review with structured output
### read
Read the authentication source code.
- type: read-file
- file_path: src/auth.py
### review
Review the authentication code and return structured findings.
- type: claude-code
- prompt: Review this authentication code: ${read.content}
```yaml output_schema
type: object
properties:
issues:
type: array
items:
type: string
description: Problems found
suggestions:
type: array
items:
type: string
description: Improvements
approved:
type: boolean
description: Ready for production
required: [issues, suggestions, approved]
```
File modification with sandbox
### refactor
Refactor the User class to use dataclasses.
- type: claude-code
- prompt: Refactor the User class to use dataclasses
- cwd: /path/to/project
- allowed_tools: ["Read", "Write", "Edit"]
```yaml sandbox
enabled: true
autoAllowBashIfSandboxed: true
excludedCommands:
- docker
```
Control what Claude can do with allowed_tools:
| Tool | Capability |
|---|
Read | Read files |
Write | Create new files |
Edit | Modify existing files |
Bash | Execute shell commands |
Task | Spawn subagents |
Glob | Find files by pattern |
Grep | Search file contents |
LS | List directory contents |
WebFetch | Fetch web content |
WebSearch | Search the web |
For read-only analysis, use ["Read", "Glob", "Grep", "LS"]. For full capability, leave unset (default allows all tools).
Limitations
- Restricted directories: Cannot use
/, /etc, /usr, /bin, /sbin, /lib, /sys, /proc as working directory
- Timeout: 5 minutes (300 seconds) default, configurable up to 1 hour
- Cost: More expensive than simple LLM calls - use for tasks that need file access and iteration
- Structured output root:
output_schema must be a top-level object on this node
Error handling
| Error | Cause | Solution |
|---|
| CLI not found | Claude Code not installed | npm install -g @anthropic-ai/claude-code |
| Connection / auth error | Not logged in (default subscription mode) | Run claude auth login, or set use_api_key: true with ANTHROPIC_API_KEY for Console billing |
| Timeout | Task too complex | Increase timeout or simplify prompt |
| Rate limit | Too many requests | Wait and retry |
The node retries failures automatically (2 attempts, conservative for expensive API).