Phantom Helix Logo

Phantom Helix Intelligence

SIERRA Invoker ScriptDevelopment Guide

Learn how to create custom Invoker scripts to extend SIERRA's functionality and automate your investigation workflows.

What are Invoker Scripts?

Invoker scripts let you run any external tool or script — in any language — directly from the SIERRA canvas. Define them in simple YAML, then run them from your investigation graph to automate tasks, call APIs, and capture results back into the graph for immediate analysis.

Copy Prompt for LLMs

Copy a ready-made Markdown prompt for ChatGPT, Claude, or any other model. It includes the valid SIERRA schema, V1/V2 output rules, and the response format we want back.

After pasting it into the model, replace the finalUser Requestsection with your workflow.

Script Structure

An Invoker script is defined by a YAML configuration file, which tells SIERRA how to present parameters, run your command, and handle its output in the graph. It has the following structure:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 # [Optional]: Working directories SIERRA will try as cwd when executing Command # These entries are not executable search roots PATHS: - /path/to/script/directory - /another/path # [Mandatory]: Contains the list of Invoker scripts SCRIPTS: - Name: Unique Script Name # [Mandatory] Description: Brief description of the script Protocol: V2 # [Optional] omit for V1 batch invokers Params: # [Mandatory] - Name: ParameterName # [Mandatory] Description: Parameter description # [Optional] # [Mandatory]: The data type of the parameter # Supported types: STRING, FILE Type: STRING Options: # [Optional] - MANDATORY # indicates this parameter cannot be empty Command: command_to_execute {ParameterName} # [Mandatory]

Protocol Versions

SIERRA currently supports two invoker output contracts:V1 for batch/final JSON, and V2 for incremental node emission.

V1: The command finishes first, then stdout is parsed once as a finalTree,Network, orErrorobject.

V2: The command writes one JSON object per line to stdout while it runs.resultevents create nodes immediately,progressupdates the invoker UI, andendcloses the stream.

V1 Output Formats

For the default V1 contract, your script should return JSON in one of these supported formats:

🌳 Tree Type Output

The type field should be Tree. Perfect for hierarchical data structures.

1 2 3 4 5 6 7 8 9 10 11 12 13 { "type": "Tree", "results": [ "Content of Entity A", "Content of Entity B", { "Content of Entity C (parent of D and E)": [ "Content of Entity D", "Content of Entity E" ] } ] }

🕸️ Network Type Output

The type field should be Network. Ideal for complex relationship mapping.

1 2 3 4 5 6 7 8 9 10 11 12 13 { "type": "Network", "origins": ["AliceID"], "nodes": [ { "id": "AliceID", "content": "Alice" }, { "id": "BobID", "content": "Bob" }, { "id": "CharlieID", "content": "Charlie" } ], "edges": [ { "source": "AliceID", "target": "BobID", "label": "friend" }, { "source": "AliceID", "target": "CharlieID", "label": "colleague" } ] }

⚠️ Error Handling

When your script encounters an error, return a JSON object with type: "Error".

1 2 3 4 5 6 7 8 9 10 11 // Service error { "type": "Error", "message": "API connection failed" } // Input validation error { "type": "Error", "message": "Invalid email format" }

Local V2 Tutorial

Use Protocol: V2 when your local invoker benefits from incremental results, such as search, scraping, enumeration, or long-running collection jobs.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 PATHS: - /opt/scripts SCRIPTS: - Name: Username Search Description: Emits usernames as they are found Protocol: V2 Params: - Name: Username Description: Username to search Type: STRING Options: - MANDATORY Command: python username_search.py "{Username}"

Your script should write one compact JSON object per line tostdout. Do not pretty-print multi-line JSON.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 import json def emit(event): print(json.dumps(event), flush=True) username = "alice" emit({ "version": 2, "type": "progress", "message": f"Searching for {username}" }) emit({ "version": 2, "type": "result", "id": "root", "content": f"# Username Search\n{username}" }) emit({ "version": 2, "type": "result", "id": "github", "parent": "root", "content": "# GitHub\nhttps://github.com/alice" }) emit({ "version": 2, "type": "end", "summary": "1 account found" })

Recommended event types: result,progress,end, anderror.

Parenting: omit parent to attach directly to the invoker node, or reference a previously emitted result id.

Logging: keep protocol events on stdout; send ordinary debug logs to stderr.

Complete Example

Here's a complete example of an Invoker script configuration for a subdomain lookup utility:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 PATHS: - /opt/scripts - /home/user/tools SCRIPTS: - Name: Subdomain Finder Description: Looks up subdomains of a given domain using crt.sh Params: - Name: Domain Description: The domain to find subdomains for Type: STRING Options: - PRIMARY - MANDATORY Command: python subfinder.py {Domain}

Best Practices

Follow these guidelines for optimal Invoker script development:

Validate inputs: Always validate parameters before processing

Handle errors gracefully: Return meaningful error messages

Use descriptive names: Make script and parameter names self-explanatory

Test thoroughly: Verify output formats work correctly in SIERRA

Document your scripts: Include helpful descriptions and examples

Ready to Build Your First Invoker?

Start building Invokers to supercharge your investigations, from quick lookups to complex multi-step automations.

Phantom Helix

OSINT tools for modern investigators and security professionals.

Product

SIERRADownloadCloud Invoker PricingDocumentation

© 2026 Phantom Helix Intelligence. All rights reserved.

Made with ❤️ for the OSINT community