How to Add a New Tool to the OpenMontage Registry Automatically

You can add a new tool to the OpenMontage registry automatically by creating a Python module in the tools/ directory that defines a concrete subclass of BaseTool, which the ToolRegistry.discover() method will detect and register at runtime without requiring explicit registration calls.

OpenMontage eliminates manual tool registration through a runtime auto-discovery system. By leveraging Python’s pkgutil module, the framework dynamically inspects the entire tools/ package tree and registers valid BaseTool subclasses automatically, allowing you to extend functionality simply by placing a file in the correct location.

How Auto-Discovery Works

The automatic registration logic resides in tools/tool_registry.py, specifically within the ToolRegistry.discover() method (lines 18-33 and 73-84). This method uses pkgutil.walk_packages() to iterate over every submodule in the tools/ package tree. For each module found, it calls register_module() to inspect the contents and collect any concrete subclasses of BaseTool.

Because this process runs at runtime, the registry stays synchronized with the filesystem. When you add a new tool file, the next call to discover() imports the module and maps the tool by its name attribute automatically.

Step-by-Step Guide to Adding a New Tool

Step 1: Create Your Tool Module

Place your new tool file under the appropriate category folder within the tools/ directory. If your tool handles video generation, for example, create it at tools/video/my_new_video_tool.py. The directory structure dictates the categorical organization, but the discovery mechanism searches recursively, so nested subdirectories are supported.

Step 2: Implement the BaseTool Subclass

Define a concrete class that inherits from BaseTool and implements all required abstract methods. You must set the following class attributes: name, provider, capability, tier, stability, and status. Additionally, you must implement the execute() method that defines the tool’s runtime behavior.

Step 3: Trigger Registry Discovery

Once your file is saved, trigger the discovery process to load the new tool. This is typically done automatically by the agent during initialization, but you can invoke it manually in scripts or REPL sessions.

Complete Working Example

Here is a fully functional example of a new video tool that will be discovered automatically:


# tools/video/my_new_video_tool.py

from tools.base_tool import BaseTool, ToolStatus, ToolTier, ToolStability

class MyNewVideoTool(BaseTool):
    """A simple example video generation tool."""

    # Required metadata attributes

    name = "my_new_video"
    provider = "my_provider"
    capability = "video_generation"
    tier = ToolTier.CORE
    stability = ToolStability.STABLE
    status = ToolStatus.AVAILABLE

    # Optional enrichment fields

    best_for = "quick prototype videos"
    install_instructions = "Add MY_PROVIDER_API_KEY to .env"
    dependencies = ["env:MY_PROVIDER_API_KEY"]

    def execute(self, **kwargs):
        """Execute the tool logic."""
        # Replace with actual provider integration

        return {"message": "MyNewVideoTool executed", "inputs": kwargs}

To verify the tool is registered, run the following discovery sequence:

from tools.tool_registry import registry

# Refresh registry - imports new modules automatically

registry.discover("tools")

# Verify registration

tool_info = registry.get("my_new_video").get_info()
print("Discovered:", tool_info)

The call to registry.discover("tools") walks the package tree, finds my_new_video_tool.py, and registers MyNewVideoTool using the logic defined in lines 81-84 of tools/tool_registry.py.

Key Files and Methods

  • tools/tool_registry.py – Contains the ToolRegistry class with discover() and register_module() methods that orchestrate the automatic loading process.

  • tools/base_tool.py – Defines the abstract BaseTool class. All auto-discovered tools must inherit from this class and implement the execute() method.

  • pkgutil.walk_packages() – The standard library function (utilized in discover()) that enables recursive module traversal without manual path configuration.

Summary

  • OpenMontage uses ToolRegistry.discover() in tools/tool_registry.py to scan for tools at runtime.
  • You only need to create a Python file in tools/<category>/ containing a BaseTool subclass.
  • Required class attributes include name, provider, capability, tier, stability, and status.
  • The execute() method must be implemented to define tool behavior.
  • No manual registration code is required; the registry updates automatically when discover() is called.

Frequently Asked Questions

Do I need to manually register my tool in a central list or configuration file?

No. As implemented in calesthio/OpenMontage, the ToolRegistry.discover() method handles registration automatically. It walks the tools/ directory tree using pkgutil.walk_packages() and registers any valid BaseTool subclass it finds, eliminating the need for manual entry in registry lists or configuration files.

What happens if two tools have the same name attribute?

The registry uses the name class attribute as the unique lookup key. If two tools define identical names, the last one discovered during the walk_packages() iteration will overwrite the previous entry. Ensure your name values are unique across the entire tools/ package to avoid collisions.

Can I organize tools in subdirectories within the category folders?

Yes. The discover() method recursively traverses the entire tools/ package tree. You can nest modules in subdirectories (e.g., tools/video/generation/) and they will still be detected and registered automatically, provided they contain valid BaseTool subclasses.

How do I verify that my tool was registered correctly after adding it?

Call registry.discover("tools") to refresh the registry, then use registry.get("your_tool_name") to retrieve the tool instance. If the return value is not None, the tool was successfully registered. You can also call get_info() on the returned object to inspect the parsed metadata.

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 →