Tools are the actions agents can take to interact with targets, analyze code, manipulate data, and coordinate testing. Each tool is a registered function that agents can invoke through the LLM interface.
Tools are registered using the @register_tool decorator:
# From strix/tools/registry.py
from strix.tools.registry import register_tool
@register_tool
def terminal_execute (
command : str ,
timeout : float | None = None ,
terminal_id : str | None = None ,
) -> dict[ str , Any]:
"""Execute a shell command in the sandbox terminal."""
manager = get_terminal_manager()
return manager.execute_command(command, timeout, terminal_id)
Tools can specify:
sandbox_execution=True (default): Execute in sandbox
sandbox_execution=False: Execute locally in CLI
Agents discover tools through XML schemas:
< terminal_tools >
< tool name = "terminal_execute" >
< description >
Execute a shell command in the sandbox terminal.
Returns command output, exit code, and working directory.
</ description >
< parameters >
< parameter name = "command" type = "string" required = "true" >
The shell command to execute (e.g., "ls -la", "curl https://api.com")
</ parameter >
< parameter name = "timeout" type = "float" required = "false" >
Execution timeout in seconds (default: 120)
</ parameter >
</ parameters >
</ tool >
</ terminal_tools >
These schemas are injected into the agent’s system prompt, allowing the LLM to understand what tools are available and how to use them.
Strix provides tools organized by capability:
Terminal
Execute shell commands in the sandbox:
# From strix/tools/terminal/terminal_actions.py
@register_tool
def terminal_execute (
command : str ,
is_input : bool = False ,
timeout : float | None = None ,
terminal_id : str | None = None ,
no_enter : bool = False ,
) -> dict[ str , Any]:
"""Execute commands with persistent terminal sessions."""
Use cases:
Running security scanners (nmap, sqlmap, nuclei)
Code analysis (grep, find, git log)
API testing (curl, httpie)
Custom exploit scripts
Example:
{
"tool" : "terminal_execute" ,
"arguments" : {
"command" : "curl -X POST https://api.example.com/login -d '{ \" user \" : \" admin' \" }'" ,
"timeout" : 30
}
}
Browser
Control a headless browser for web application testing:
# From strix/tools/browser/browser_actions.py
@register_tool
def browser_action (
action : BrowserAction, # launch, goto, click, type, scroll, etc.
url : str | None = None ,
coordinate : str | None = None , # Format: "x,y"
text : str | None = None ,
tab_id : str | None = None ,
js_code : str | None = None ,
) -> dict[ str , Any]:
"""Perform browser actions with screenshot feedback."""
Available actions:
launch: Start browser (with optional URL)
goto: Navigate to URL
click: Click element at coordinates
type: Type text into focused element
scroll_down / scroll_up: Scroll page
execute_js: Run JavaScript code
new_tab / switch_tab / close_tab: Tab management
save_pdf: Capture page as PDF
get_console_logs: Retrieve console messages
view_source: Get page HTML source
Example workflow:
# Launch browser and navigate
browser_action( action = "launch" , url = "https://example.com" )
# Click login button at coordinates
browser_action( action = "click" , coordinate = "500,300" )
# Type username
browser_action( action = "type" , text = "admin" )
# Execute JavaScript to extract data
browser_action(
action = "execute_js" ,
js_code = "return document.cookie"
)
Every browser action returns a screenshot (base64 encoded) showing the current page state, enabling visual feedback for agents.
File Operations
Read, write, and edit files in the workspace:
# From strix/tools/file_edit/file_edit_actions.py
@register_tool
def read_file (
file_path : str ,
start_line : int | None = None ,
end_line : int | None = None ,
) -> dict[ str , Any]:
"""Read file contents with optional line range."""
@register_tool
def write_file (
file_path : str ,
content : str ,
mode : str = "overwrite" , # overwrite | append
) -> dict[ str , Any]:
"""Write content to file."""
@register_tool
def edit_file (
file_path : str ,
old_content : str ,
new_content : str ,
occurrence : int = 1 ,
) -> dict[ str , Any]:
"""Edit file by replacing specific content."""
Use cases:
Analyzing source code for vulnerabilities
Creating exploit scripts
Modifying payloads or configurations
Extracting secrets from config files
Proxy
Interact with the Caido proxy for HTTP/HTTPS traffic analysis:
# From strix/tools/proxy/proxy_actions.py
@register_tool
def proxy_search (
query : str ,
limit : int = 50 ,
) -> dict[ str , Any]:
"""Search proxy history with filters."""
@register_tool
def proxy_replay (
request_id : str ,
modifications : dict[ str , Any] | None = None ,
) -> dict[ str , Any]:
"""Replay HTTP request with optional modifications."""
@register_tool
def proxy_get_request (
request_id : str ,
) -> dict[ str , Any]:
"""Get full request/response details."""
Use cases:
Finding authentication tokens in traffic
Replaying requests with modified parameters
Analyzing API endpoints and data flows
Detecting sensitive data in responses
Example:
# Search for authentication endpoints
proxy_search( query = "path:/login OR path:/auth" , limit = 10 )
# Replay login request with SQL injection
proxy_replay(
request_id = "req_abc123" ,
modifications = {
"body" : { "username" : "admin'--" , "password" : "anything" }
}
)
Python Execution
Run Python code in the sandbox:
# From strix/tools/python/python_actions.py
@register_tool
def python_execute (
code : str ,
timeout : float | None = None ,
) -> dict[ str , Any]:
"""Execute Python code with security libraries available."""
Available libraries:
requests, httpx - HTTP clients
beautifulsoup4, lxml - HTML parsing
jwt, cryptography - Security operations
sqlparse - SQL parsing
pycryptodome - Cryptographic operations
Example:
python_execute( code = """
import jwt
import json
# Decode JWT without verification to inspect claims
token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
header = jwt.get_unverified_header(token)
payload = jwt.decode(token, options={"verify_signature": False})
print(json.dumps({"header": header, "payload": payload}, indent=2))
""" )
Agent Coordination
Create and manage sub-agents:
# From strix/tools/agents_graph/agents_graph_actions.py
@register_tool
def create_agent (
task : str ,
name : str ,
skills : str | None = None , # Comma-separated skill names
inherit_messages : bool = False ,
) -> dict[ str , Any]:
"""Create a specialized sub-agent for a specific task."""
@register_tool
def send_message_to_agent (
recipient_agent_id : str ,
message : str ,
message_type : str = "information" ,
priority : str = "normal" ,
) -> dict[ str , Any]:
"""Send message to another agent."""
@register_tool
def agent_finish (
result : str ,
success : bool = True ,
) -> dict[ str , Any]:
"""Complete sub-agent task and report back to parent."""
Example:
# Create specialized agent for GraphQL testing
create_agent(
task = "Test all GraphQL mutations for authorization bypasses" ,
name = "GraphQL Security Tester" ,
skills = "broken_function_level_authorization,idor,graphql" ,
inherit_messages = False
)
# Send findings to parent
send_message_to_agent(
recipient_agent_id = "agent_parent123" ,
message = "Found IDOR in updateUser mutation - any user can modify any profile" ,
message_type = "information" ,
priority = "high"
)
Vulnerability Reporting
Create structured security findings:
# From strix/tools/reporting/reporting_actions.py
@register_tool
def create_vulnerability_report (
title : str ,
description : str ,
impact : str ,
target : str ,
technical_analysis : str ,
poc_description : str ,
poc_script_code : str , # REQUIRED: Actual exploit code
remediation_steps : str ,
cvss_breakdown : str , # XML format with CVSS metrics
endpoint : str | None = None ,
method : str | None = None ,
cve : str | None = None ,
cwe : str | None = None ,
code_locations : str | None = None , # XML format
) -> dict[ str , Any]:
"""Create vulnerability report with automatic CVSS calculation."""
Example:
create_vulnerability_report(
title = "SQL Injection in User Search" ,
description = "The search parameter is directly interpolated into SQL query" ,
impact = "Attackers can extract entire database including passwords and PII" ,
target = "https://api.example.com/users/search" ,
endpoint = "/users/search" ,
method = "POST" ,
cwe = "CWE-89" ,
technical_analysis = """
The backend constructs SQL query using string concatenation:
query = f"SELECT * FROM users WHERE name LIKE '% {search_term} %'"
This allows SQL injection through the search_term parameter.
""" ,
poc_description = "Send POST request with SQL injection payload in search parameter" ,
poc_script_code = """
curl -X POST https://api.example.com/users/search \
-H 'Content-Type: application/json' \
-d '{"search": "' UNION SELECT username,password,email FROM users--"}'
""" ,
remediation_steps = """
1. Use parameterized queries or ORM with parameter binding
2. Validate and sanitize all user input
3. Implement least-privilege database access
4. Add Web Application Firewall rules
""" ,
cvss_breakdown = """
<cvss>
<attack_vector>N</attack_vector>
<attack_complexity>L</attack_complexity>
<privileges_required>N</privileges_required>
<user_interaction>N</user_interaction>
<scope>U</scope>
<confidentiality>H</confidentiality>
<integrity>H</integrity>
<availability>N</availability>
</cvss>
""" ,
code_locations = """
<code_locations>
<location>
<file>src/api/users.py</file>
<start_line>145</start_line>
<end_line>147</end_line>
<snippet>
query = f"SELECT * FROM users WHERE name LIKE '% {search_term} %'"
cursor.execute(query)
results = cursor.fetchall()
</snippet>
</location>
</code_locations>
"""
)
The reporting tool automatically:
Calculates CVSS score from metrics
Checks for duplicate findings
Validates required fields and formats
Extracts CVE/CWE identifiers from text
Thinking & Notes
Internal tools for agent reasoning:
@register_tool ( sandbox_execution = False )
def think (
thought : str ,
) -> dict[ str , Any]:
"""Record reasoning and planning (not shown to user)."""
@register_tool ( sandbox_execution = False )
def note (
content : str ,
category : str = "general" ,
) -> dict[ str , Any]:
"""Save important information for later reference."""
Use cases:
Planning testing strategy
Recording discovered credentials or endpoints
Tracking hypotheses and next steps
TODO Management
Track tasks and progress:
@register_tool ( sandbox_execution = False )
def todo_create (
title : str ,
description : str | None = None ,
) -> dict[ str , Any]:
"""Create a new task."""
@register_tool ( sandbox_execution = False )
def todo_update (
todo_id : str ,
status : str , # pending | in_progress | completed | cancelled
) -> dict[ str , Any]:
"""Update task status."""
Scan Control
Finish the scan and return results:
# From strix/tools/finish/finish_actions.py
@register_tool ( sandbox_execution = False )
def finish_scan (
summary : str ,
total_findings : int = 0 ,
) -> dict[ str , Any]:
"""Complete the scan (root agent only)."""
Sandbox Execution
Most tools execute in the sandbox for isolation:
# From strix/tools/executor.py
async def _execute_tool_in_sandbox ( tool_name : str , agent_state , ** kwargs ):
server_url = await runtime.get_sandbox_url(
agent_state.sandbox_id,
agent_state.sandbox_info[ "tool_server_port" ]
)
# Send HTTP request to tool server in sandbox
async with httpx.AsyncClient() as client:
response = await client.post(
f " { server_url } /execute" ,
json = { "tool_name" : tool_name, "kwargs" : kwargs},
headers = { "Authorization" : f "Bearer { agent_state.sandbox_token } " },
timeout = SANDBOX_EXECUTION_TIMEOUT ,
)
Sandbox tools include:
terminal_execute
browser_action
read_file, write_file, edit_file
proxy_search, proxy_replay
python_execute
Local Execution
Some tools run in the CLI for performance or security:
@register_tool ( sandbox_execution = False )
def create_agent (...):
# Runs locally to manage agent lifecycle
Local tools include:
create_agent, send_message_to_agent
create_vulnerability_report
think, note
todo_create, todo_update
finish_scan, agent_finish
All tools return structured dictionaries:
# Success case
{
"success" : True ,
"output" : "command output here" ,
"exit_code" : 0 ,
"working_dir" : "/workspace"
}
# Error case
{
"success" : False ,
"error" : "File not found: config.json" ,
"details" : { ... }
}
Agent LLMs receive these results as XML in the conversation:
< tool_result name = "terminal_execute" >
< success > true </ success >
< output >
total 48
drwxr-xr-x 3 agent agent 4096 Mar 1 10:30 src
drwxr-xr-x 2 agent agent 4096 Mar 1 10:25 tests
-rw-r--r-- 1 agent agent 1234 Mar 1 10:20 package.json
</ output >
< exit_code > 0 </ exit_code >
</ tool_result >
Web Search (Optional)
If Perplexity API key is configured:
@register_tool ( sandbox_execution = False )
def web_search (
query : str ,
search_type : str = "general" , # general | vulnerability | exploit
) -> dict[ str , Any]:
"""Search the web for security information."""
Enable with:
export PERPLEXITY_API_KEY = "pplx-..."
strix scan --target https://app.com
You can register custom tools:
from strix.tools.registry import register_tool
@register_tool
def my_custom_tool (
param1 : str ,
param2 : int = 10 ,
) -> dict[ str , Any]:
"""My custom security testing tool."""
# Tool implementation
return {
"success" : True ,
"result" : "custom result"
}
Create an XML schema file for the tool in ~/.strix/tools/custom/:
< tool name = "my_custom_tool" >
< description > My custom security testing tool </ description >
< parameters >
< parameter name = "param1" type = "string" required = "true" >
Description of param1
</ parameter >
< parameter name = "param2" type = "integer" required = "false" >
Description of param2 (default: 10)
</ parameter >
</ parameters >
</ tool >
Next Steps
Skills Learn how skills enhance agent capabilities
Agents Understand agent architecture
How It Works See the full execution flow
Vulnerability Detection Explore security testing patterns