# How to Add a New Tool to the OpenMontage Registry Automatically

> Automatically add new tools to the OpenMontage registry by creating a Python module in the tools directory. Discover and register tools at runtime without manual steps.

- Repository: [Calesthio/OpenMontage](https://github.com/calesthio/OpenMontage)
- Tags: how-to-guide
- Published: 2026-08-30

---

**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`](https://github.com/calesthio/OpenMontage/blob/main/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`](https://github.com/calesthio/OpenMontage/blob/main/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:

```python

# 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:

```python
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`](https://github.com/calesthio/OpenMontage/blob/main/my_new_video_tool.py), and registers `MyNewVideoTool` using the logic defined in lines 81-84 of [`tools/tool_registry.py`](https://github.com/calesthio/OpenMontage/blob/main/tools/tool_registry.py).

## Key Files and Methods

- **[`tools/tool_registry.py`](https://github.com/calesthio/OpenMontage/blob/main/tools/tool_registry.py)** – Contains the `ToolRegistry` class with `discover()` and `register_module()` methods that orchestrate the automatic loading process.

- **[`tools/base_tool.py`](https://github.com/calesthio/OpenMontage/blob/main/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`](https://github.com/calesthio/OpenMontage/blob/main/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.