Overview
Tool nodes let you integrate external services and custom Python code directly into your workflow — without needing to write an LLM prompt. Any node withtype: tool is a tool node.
Common fields
All tool nodes share these top-level fields.output_key and context storage
Tool output is stored under the node ID and its output_key. For example, a node named fetch_diff with output_key: diff exposes its result as {{ fetch_diff.diff }}. Downstream agent nodes reference this value in their system prompts using Jinja-style template syntax:
output_key is omitted it defaults to output, so the reference becomes {{ <node_id>.output }}.
Reference upstream nodes by their ID (
{{ fetch_diff.diff }}), not via the
working namespace. The load-time linter rejects {{ working.<node_id>.* }}.
Reserve working.* for custom paths you write to or seed in state.HTTP adapter
Usetool: http to call an HTTP endpoint.
HTTP config fields
Response handling
- If the response
Content-Typeisapplication/json, the body is parsed and the result is a Python dict or list. - Otherwise, the raw response text string is stored.
Error behaviour
Any non-2xx status code raises aToolError with the HTTP status code and response body excerpt in the message. Network errors (DNS failures, connection refused) and timeouts also raise ToolError.
Python adapter
Usetool: python to call any importable Python function.
Python config fields
Module resolution
The module is resolved usingimportlib.import_module against the user’s runtime environment (sys.path), not against the sirenspec package. This means any module that is importable in the process where sirenspec runs can be used — your own application code, installed packages, or local scripts.
Synchronous functions are run in a thread-pool executor so they do not block the event loop. Async functions are awaited directly.
Error behaviour
ModuleNotFoundError→ToolErrorwith message"Cannot import module '...'"- Missing attribute →
ToolErrorwith message"Module '...' has no attribute '...'" - Exception during call →
ToolErrorwith the original exception type and message included
Retry and failure handling
retry: N— the tool is attemptedN + 1times total before giving up.on_failure: raise(default) — propagates aToolErrorand marks the workflow as"failed".on_failure: skip— storesnullunder the output key and lets the workflow continue.
Full example: PR summarizer
This workflow fetches a GitHub pull-request diff over HTTP and then asks an LLM to summarise it.ToolError
All tool failures raisesirenspec.exceptions.ToolError (a subclass of SirenSpecError). The exception message always includes the adapter name and the upstream error:
ToolError exposes three attributes:
JSON Schema
Thesirenspec.schema.json artifact validates tool nodes inline with agent nodes. IDEs that support JSON Schema (VS Code, JetBrains) will autocomplete type: tool, tool:, and all config fields automatically.