Skip to main content
The ToolNode class runs a Fibonacci platform tool — connecting workflows to services like Google Sheets, Slack, databases, and HTTP APIs.

Constructor

from fibonacci import ToolNode

node = ToolNode(
    id="fetch_data",
    name="Fetch Sheet Data",
    tool="google_sheets_read",
    params={
        "spreadsheet_id": "{{input.sheet_id}}",
        "range": "A1:D100"
    }
)

Parameters

ParameterTypeDefaultDescription
idstrRequiredUnique node identifier (lowercase letters, numbers, underscores, hyphens)
namestrRequiredHuman-readable node name
toolstrRequiredTool name (e.g., "google_sheets_read", "slack_send_message")
paramsdictRequiredInput parameters for the tool — supports {{variable}} template syntax
timeoutint30Execution timeout in seconds
dependencieslist[str][]Node IDs this node waits for before running
enable_retryboolFalseRetry on failure
max_retriesint3Maximum retry attempts (used when enable_retry=True)
retry_delayfloat1.0Initial delay in seconds between retries
Tool names use underscore format (e.g., google_sheets_read, slack_send_message). Use list_tools() or print_tool_info() to see available tools and their exact names.

Template Variables in Params

Any value in params can reference dynamic data:
node = ToolNode(
    id="notify",
    name="Send Notification",
    tool="slack_send_message",
    params={
        "channel": "#{{input.team}}",
        "message": "Analysis complete: {{analyze_data}}"
    }
)
SyntaxSource
{{input.field}}Workflow input data
{{node_id}}Full output of another node
{{node_id.field}}Specific field from a node’s JSON output

Tool Categories

Google Workspace

# Read from Google Sheets
read_sheet = ToolNode(
    id="read_sheet",
    name="Read Sheet",
    tool="google_sheets_read",
    params={
        "spreadsheet_id": "{{input.sheet_id}}",
        "range": "Sheet1!A1:D100"
    }
)

# Write to Google Sheets
write_sheet = ToolNode(
    id="write_sheet",
    name="Write Results",
    tool="google_sheets_write",
    params={
        "spreadsheet_id": "{{input.sheet_id}}",
        "range": "Results!A1",
        "values": [["Name", "Score"], ["Alice", "95"]]
    }
)

# Append rows
append_row = ToolNode(
    id="append_row",
    name="Append Log Row",
    tool="google_sheets_append",
    params={
        "spreadsheet_id": "{{input.sheet_id}}",
        "range": "Log!A:D",
        "values": [["{{input.id}}", "{{analyze_data}}"]]
    }
)

# Read a Google Doc
read_doc = ToolNode(
    id="read_doc",
    name="Read Document",
    tool="google_docs_read",
    params={
        "document_id": "{{input.doc_id}}"
    }
)

# Create a Google Doc
create_doc = ToolNode(
    id="create_doc",
    name="Create Document",
    tool="google_docs_create",
    params={
        "title": "{{input.title}}",
        "content": "{{generate_report}}"
    }
)

# Send email via Gmail
send_email = ToolNode(
    id="send_email",
    name="Send Email",
    tool="gmail_send",
    params={
        "to": "recipient@example.com",
        "subject": "Your Report is Ready",
        "body": "{{executive_summary}}"
    }
)

# Create a Google Calendar event
create_event = ToolNode(
    id="create_event",
    name="Schedule Meeting",
    tool="google_calendar_create_event",
    params={
        "summary": "Follow-up Meeting",
        "start": "2025-06-01T10:00:00",
        "end": "2025-06-01T11:00:00",
        "attendees": ["team@company.com"]
    }
)

Communication

# Slack — send a message
slack_msg = ToolNode(
    id="notify_team",
    name="Notify Team",
    tool="slack_send_message",
    params={
        "channel": "#team-updates",
        "message": "Report ready: {{executive_summary}}"
    }
)

# Slack — DM a user
slack_dm = ToolNode(
    id="dm_user",
    name="DM User",
    tool="slack_send_message",
    params={
        "channel": "@john.doe",
        "message": "Your task is complete."
    }
)

HTTP & APIs

# Generic HTTP request
api_call = ToolNode(
    id="call_api",
    name="Call External API",
    tool="http_request",
    params={
        "method": "POST",
        "url": "https://api.example.com/data",
        "headers": {
            "Authorization": "Bearer {{input.api_token}}",
            "Content-Type": "application/json"
        },
        "body": {
            "query": "{{input.search_term}}"
        }
    }
)

# Webhook
webhook = ToolNode(
    id="trigger_webhook",
    name="Trigger Webhook",
    tool="webhook_call",
    params={
        "url": "https://hooks.zapier.com/hooks/catch/123/abc",
        "payload": {
            "event": "report_generated",
            "data": "{{report_data}}"
        }
    }
)

Databases

query = ToolNode(
    id="query_db",
    name="Query Database",
    tool="database_query",
    params={
        "connection_string": "{{secrets.DATABASE_URL}}",
        "query": """
            SELECT customer_id, SUM(amount) AS total
            FROM orders
            WHERE date >= '{{input.start_date}}'
            GROUP BY customer_id
            ORDER BY total DESC
            LIMIT 10
        """
    }
)
Never hardcode database credentials. Use the secrets parameter in wf.run() or the Fibonacci secrets manager.

Cloud Storage

# Upload to S3
s3_upload = ToolNode(
    id="upload_s3",
    name="Upload to S3",
    tool="s3_upload",
    params={
        "bucket": "my-reports",
        "key": "reports/{{input.report_id}}.pdf",
        "content": "{{report_pdf}}",
        "content_type": "application/pdf"
    }
)

# Download from S3
s3_download = ToolNode(
    id="download_s3",
    name="Download from S3",
    tool="s3_download",
    params={
        "bucket": "my-data",
        "key": "data/{{input.file_name}}"
    }
)

CRM & Business

# Create a Salesforce lead
create_lead = ToolNode(
    id="create_lead",
    name="Create Salesforce Lead",
    tool="salesforce_create",
    params={
        "object": "Lead",
        "data": {
            "FirstName": "{{input.first_name}}",
            "LastName": "{{input.last_name}}",
            "Email": "{{input.email}}",
            "Company": "{{input.company}}"
        }
    }
)

# Update a HubSpot contact
hubspot_contact = ToolNode(
    id="update_contact",
    name="Update HubSpot Contact",
    tool="hubspot_update_contact",
    params={
        "email": "{{input.email}}",
        "properties": {
            "lead_score": "{{score_lead}}"
        }
    }
)

# Create a Notion page
notion_page = ToolNode(
    id="create_notion",
    name="Create Notion Page",
    tool="notion_create_page",
    params={
        "database_id": "{{input.database_id}}",
        "properties": {
            "Name": "{{input.title}}",
            "Status": "Ready"
        },
        "content": "{{generate_notes}}"
    }
)

Tool Discovery

List Available Tools

from fibonacci import list_tools, list_tool_categories

# All tools
tools = list_tools()
for tool in tools:
    print(f"{tool['name']}: {tool['description']}")

# By category
categories = list_tool_categories()
for cat in categories:
    print(f"{cat['name']}: {cat['count']} tools")

Search Tools

from fibonacci import search_tools

results = search_tools("slack")
for tool in results:
    print(f"{tool['name']}: {tool['description']}")

Inspect a Tool

from fibonacci import print_tool_info

print_tool_info("google_sheets_read")
Output:
======================================================================
🔧 google_sheets_read
======================================================================
Category: google_workspace
Description: Read data from a Google Sheets spreadsheet

📥 Input Parameters:
  • spreadsheet_id (string) - required
  • range (string) - required
    A1 notation range (e.g., "Sheet1!A1:D10")

📖 Examples:
  1. Read sales data
     Params: {"spreadsheet_id": "abc123", "range": "Sales!A1:E100"}
======================================================================

Find the Right Tool

from fibonacci import find_tool_for_task

tool = find_tool_for_task("send a message to slack")
print(tool)  # "slack_send_message"

tool = find_tool_for_task("read data from google sheets")
print(tool)  # "google_sheets_read"

Dependencies

# Read data
read = ToolNode(
    id="read_source",
    name="Read Source Sheet",
    tool="google_sheets_read",
    params={"spreadsheet_id": "...", "range": "A1:Z100"}
)

# Write results (waits for read to finish)
write = ToolNode(
    id="write_dest",
    name="Write Destination Sheet",
    tool="google_sheets_write",
    params={
        "spreadsheet_id": "...",
        "range": "A1",
        "values": "{{read_source}}"
    },
    dependencies=["read_source"]
)

Timeout Configuration

slow_api = ToolNode(
    id="slow_api",
    name="Long-Running API",
    tool="http_request",
    params={"url": "https://api.example.com/slow-endpoint"},
    timeout=120   # override the 30s default
)

Retry Configuration

# Via constructor
api_call = ToolNode(
    id="api_call",
    name="Reliable API Call",
    tool="http_request",
    params={"url": "https://api.example.com"},
    enable_retry=True,
    max_retries=5,
    retry_delay=2.0
)

# Via fluent method
api_call = ToolNode(
    id="api_call",
    name="Reliable API Call",
    tool="http_request",
    params={"url": "https://api.example.com"}
).with_retry(max_retries=5, delay=2.0)

Conditional Execution

notify_urgent = ToolNode(
    id="notify_urgent",
    name="Notify Urgent",
    tool="slack_send_message",
    params={
        "channel": "#urgent",
        "message": "Urgent issue: {{analyzer}}"
    }
).with_condition(
    left_value="{{analyzer_urgency}}",
    operator="equals",
    right_value="high"
)

YAML Configuration

nodes:
  - id: notify
    name: Notify Team
    type: tool
    tool_name: slack_send_message
    tool_params:
      channel: "#analytics"
      message: "Analysis complete: {{analyze}}"
    dependencies:
      - analyze

Complete Example

from fibonacci import Workflow, LLMNode, ToolNode

wf = Workflow(name="data-pipeline")

# Fetch data
fetch = ToolNode(
    id="fetch_data",
    name="Read Sheet",
    tool="google_sheets_read",
    params={
        "spreadsheet_id": "{{input.sheet_id}}",
        "range": "Data!A1:Z1000"
    }
)

# Analyze with LLM
analyze = LLMNode(
    id="analyze",
    name="Analyze Data",
    instruction="Analyze this data and find key insights: {{fetch_data}}",
    model="claude-sonnet-4-6",
    dependencies=["fetch_data"]
)

# Notify via Slack
notify = ToolNode(
    id="notify",
    name="Send Report",
    tool="slack_send_message",
    params={
        "channel": "#analytics",
        "message": "Analysis complete for {{input.sheet_id}}:\n{{analyze}}"
    },
    dependencies=["analyze"]
)

wf.add_nodes([fetch, analyze, notify])

result = wf.run(input_data={"sheet_id": "abc123"})
print(result.output_data)