How to Create and Register Custom Tools in the Strix Tool Registry

Use the @register_tool decorator from strix/tools/registry.py on any Python function to automatically add it to the agent runtime, with optional flags to control sandbox execution, browser requirements, and web-search dependencies.

Strix provides a centralized tool registry that automatically discovers and validates functions for agent consumption. Located in strix/tools/registry.py, this registry enables developers to extend agent capabilities by writing plain Python functions and decorating them with @register_tool. This guide demonstrates how to create and register custom tools in the Strix tool registry while respecting environment constraints like sandbox mode and API availability.

Understanding the Tool Registry Architecture

The Strix tool registry implements automatic discovery and conditional loading of tool-functions. According to the usestrix/strix source code, the registry handles four primary responsibilities:

  • Conditional registration – evaluates sandbox mode, browser disabling, and Perplexity API key presence before adding tools
  • Module discovery – records the tool's name, callable reference, and originating module (e.g., terminal, web_search)
  • XML schema loading – attaches parameter descriptions from *_schema.xml files when not in sandbox mode
  • Parameter extraction – parses required and optional arguments to power UI prompt rendering

The core registration logic resides in strix/tools/registry.py, specifically within the _should_register_tool function (lines 75-89) and the register_tool decorator definition (lines 90-101).

The @register_tool Decorator Explained

The @register_tool decorator evaluates environment conditions before adding a function to the internal tools list. It accepts three optional boolean parameters:

  • sandbox_execution (default: True) – whether the tool runs in sandboxed environments
  • requires_browser_mode (default: False) – whether the tool requires browser automation
  • requires_web_search_mode (default: False) – whether the tool requires a Perplexity API key

The decorator calls _should_register_tool to implement the following gating logic:

def _should_register_tool(
    *,
    sandbox_execution: bool,
    requires_browser_mode: bool,
    requires_web_search_mode: bool,
) -> bool:
    sandbox_mode = _is_sandbox_mode()

    # Sandbox mode: only tools that explicitly allow sandbox execution are kept

    if sandbox_mode and not sandbox_execution:
        return False
    # Browser mode disabled → drop any tool that needs a browser

    if requires_browser_mode and _is_browser_disabled():
        return False
    # Web-search mode requires a Perplexity API key

    return not (requires_web_search_mode and not _has_perplexity_api())

When conditions pass, the decorator extracts the function name, module path, and optionally loads an XML schema file to populate the tool's metadata.

Creating Your First Custom Tool

Building a custom tool requires three components: the Python implementation, optional XML schema documentation, and module registration.

Writing the Python Function

Create a new file under strix/tools/<category>/ with a typed function signature. The function must return a JSON-serializable dictionary that the agent runtime can process.


# file: strix/tools/example/echo_actions.py

from strix.tools.registry import register_tool

@register_tool
def echo(message: str) -> dict[str, str]:
    """Return the input message unchanged."""
    return {"echo": message}

This minimal example uses default decorator settings, making it available in both sandbox and full execution modes.

Adding XML Schema Definitions

For non-sandbox deployments, create a matching *_schema.xml file in the same directory. The registry loads this automatically to provide parameter descriptions to the UI layer.

<!-- file: strix/tools/example/echo_actions_schema.xml -->
<tool name="echo">
  <description>Return the input message unchanged.</description>
  <parameters>
    <parameter name="message" type="string" required="true"/>
  </parameters>
</tool>

If the schema file is missing while running in standard mode, the registry falls back to a placeholder message.

Conditional Registration Patterns

Strix supports specialized execution contexts through decorator flags.

Sandbox-Only Tools

Tools that perform filesystem operations or execute arbitrary code should disable sandbox execution to prevent security risks:


# file: strix/tools/filesystem/dangerous_actions.py

from strix.tools.registry import register_tool

@register_tool(sandbox_execution=False)
def delete_file(path: str) -> dict[str, str]:
    """Delete a file at the specified path."""
    import os
    os.remove(path)
    return {"status": "deleted", "path": path}

Browser-Dependent Tools

Tools requiring browser automation must specify requires_browser_mode=True. These automatically unregister when STRIX_DISABLE_BROWSER=true:


# file: strix/tools/browser/open_url_actions.py

import webbrowser
from strix.tools.registry import register_tool

@register_tool(requires_browser_mode=True)
def open_url(url: str) -> dict[str, str]:
    """Open the given URL in the system browser."""
    webbrowser.open(url)
    return {"status": "opened", "url": url}

Web-Search Tools

Tools integrating with Perplexity AI require both sandbox_execution=False and requires_web_search_mode=True:


# file: strix/tools/web_search/custom_search_actions.py

import os
import requests
from strix.tools.registry import register_tool

@register_tool(sandbox_execution=False, requires_web_search_mode=True)
def custom_search(query: str) -> dict[str, str]:
    """Search the web using Perplexity AI."""
    api_key = os.getenv("PERPLEXITY_API_KEY")
    resp = requests.post(
        "https://api.perplexity.ai/chat/completions",
        headers={"Authorization": f"Bearer {api_key}"},
        json={
            "model": "sonar-small",
            "messages": [{"role": "user", "content": query}]
        },
        timeout=30,
    )
    return {"answer": resp.json()["choices"][0]["message"]["content"]}

Activating Custom Tools

Registration occurs at module import time. To activate your custom tool, import it into strix/tools/__init__.py or any module guaranteed to load at startup:


# file: strix/tools/__init__.py

from .example.echo_actions import echo
from .browser.open_url_actions import open_url
from .web_search.custom_search_actions import custom_search

After import, the get_tools_prompt() function includes your tool in the generated system prompt, making it available to the agent.

Summary

  • Use @register_tool from strix/tools/registry.py to expose Python functions to the Strix agent runtime
  • Implement conditional logic via sandbox_execution, requires_browser_mode, and requires_web_search_mode parameters to respect environment constraints
  • Provide XML schemas in *_schema.xml files alongside your Python modules to enable rich UI descriptions in non-sandbox mode
  • Import the module in strix/tools/__init__.py to trigger registration at application startup
  • Reference test cases in tests/tools/test_tool_registration_modes.py (lines 24-59) to understand how environment variables gate tool availability

Frequently Asked Questions

What happens if I don't provide an XML schema file?

If STRIX_SANDBOX_MODE is disabled and no schema file exists, the registry uses a placeholder description. The tool remains functional but lacks parameter documentation in the UI. In sandbox mode, schema loading is skipped entirely.

Can I register multiple tools in the same file?

Yes. Apply @register_tool to each function in the module. Each decorator executes independently at import time, adding separate entries to the registry. Group related tools (e.g., all filesystem operations) in the same file under strix/tools/<category>/.

Why isn't my tool appearing in the agent's tool list?

Verify that: (1) The module containing your tool is imported in strix/tools/__init__.py, (2) Environment flags match your decorator parameters (check STRIX_SANDBOX_MODE, STRIX_DISABLE_BROWSER, and PERPLEXITY_API_KEY), and (3) The function returns a dictionary or serializable object. Review the conditional logic in _should_register_tool in strix/tools/registry.py lines 75-89 to debug gating issues.

Can I modify tool availability at runtime?

No. Registration occurs once at module import time when the @register_tool decorator executes. The internal tools list is populated during this phase based on environment variables present at startup. To change availability, you must restart the application with different environment variables (e.g., toggling STRIX_SANDBOX_MODE) or modify the import statements in strix/tools/__init__.py.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →