Skip to content

Custom Tools & Python Plugins

Hermes has 60+ built-in tools, but your environment has its own, an internal API, a deployment script, a database query that matters to your team. You can register custom tools that appear alongside the built-in ones, gated by the same toolset and approval system. This lesson covers the tool registry and backend plugins.

Gnome mascot

What you'll learn

  • Custom tools are registered in Python, one file in tools/, one entry in toolsets.py
  • All handlers must return JSON strings and include a check_fn so the tool only appears when its requirements are met
  • Backend plugins (~/.hermes/plugins/) are Python packages that load at startup, use them for tools you don't want in the core repo

The problem

Built-in tools cover files, terminal, web, browser, and more. But they don't cover your internal API, your deployment system, or your team's specific workflows. Custom tools fill that gap. They're first-class, they appear in hermes tools list, respect the approval system, and are gated by toolset enable/disable just like built-in tools.

Options & when to use each

ApproachGood forWhen to use it
Custom tool in coreTools you want to contribute back, or tools tightly coupled to your Hermes installPermanent additions to your Hermes setup
Backend plugin (~/.hermes/plugins/)Tools specific to your environment, not meant for upstreamTeam-specific tools, internal APIs, anything you don't want in the core repo
MCP serverTools that already exist as a server, or tools shared across multiple agent platformsExisting services, cross-platform tools
Desktop pluginUI extensions, not tool extensionsVisual dashboards, status panels, command palette entries

Build it: a custom tool

Step 1: Create the tool file

Create tools/health_check.py in your Hermes source directory (~/.hermes/hermes-agent/tools/):

python
import json
import subprocess
from tools.registry import registry

def check_requirements() -> bool:
    """Only show this tool if the health check script exists."""
    import os
    return os.path.exists("/usr/local/bin/health-check")

def health_check_tool(service: str = "", task_id: str = None) -> str:
    """Run a health check on a specified service or all services."""
    if service:
        result = subprocess.run(
            ["/usr/local/bin/health-check", "--service", service],
            capture_output=True, text=True, timeout=30
        )
    else:
        result = subprocess.run(
            ["/usr/local/bin/health-check", "--all"],
            capture_output=True, text=True, timeout=30
        )

    return json.dumps({
        "success": result.returncode == 0,
        "service": service or "all",
        "output": result.stdout,
        "errors": result.stderr,
    })

registry.register(
    name="health_check",
    toolset="custom",
    schema={
        "name": "health_check",
        "description": "Run a health check on a specified service or all services. "
                       "Use this to verify that services are running correctly.",
        "parameters": {
            "type": "object",
            "properties": {
                "service": {
                    "type": "string",
                    "description": "The service name to check. Omit to check all services.",
                },
            },
        },
    },
    handler=lambda args, **kw: health_check_tool(
        service=args.get("service", ""),
        task_id=kw.get("task_id"),
    ),
    check_fn=check_requirements,
    requires_env=[],
)

Step 2: Wire it into a toolset

In toolsets.py, add the tool name to a toolset:

python
# In the TOOLSETS dict:
"custom": {
    "health_check",
    # ... other custom tools
},

Or add it to _HERMES_CORE_TOOLS if you want it available on every platform by default.

Step 3: Enable the toolset

Enable the new toolset via the CLI to make it available to the agent. This step connects your Python handler to the active session.

bash
hermes tools enable custom

Then /reset to start a new session with the updated toolset. Tool changes don't take effect mid-conversation, this preserves prompt caching.

Step 4: Verify the tool is available

Check the active tool registry to confirm your setup. You should see the health check tool listed and ready for invocation.

bash
hermes tools list | grep health_check

Build it: a backend plugin

For tools you don't want in the core repo, write a backend plugin:

bash
mkdir -p ~/.hermes/plugins/my-tools

Create ~/.hermes/plugins/my-tools/__init__.py:

python
def register_tools(registry):
    """Called at startup. Register your tools here."""
    from .health_check import register_health_check
    register_health_check(registry)

Backend plugins are Python packages that load at Hermes startup. They're isolated from the core repo, update Hermes without losing your custom tools.

What goes wrong

MistakeHow you notice itThe fix
Tool doesn't appear in the tool listhermes tools list doesn't show your toolThe toolset isn't enabled, or the check_fn returned False. Enable the toolset with hermes tools enable, and verify the check_fn succeeds by running its conditions manually
Tool returns non-JSONHermes errors when parsing the tool outputAll handlers must return JSON strings. Wrap your output in json.dumps()
Tool works in CLI but not gatewayWorks in hermes chat but not from Telegram/DiscordGateway sessions may have different toolsets enabled. Run hermes tools and check the per-platform enablement
Hardcoded paths break across machinesTool works on your machine but not on the serverUse get_hermes_home() from hermes_constants for all paths, never hardcode ~/.hermes/

Confirm it worked

Run through this quick test sequence to validate your custom tool integration. This confirms the registry, enables the toolset, and invokes it within a chat session.

bash
# 1. Verify the tool is registered
hermes tools list | grep health_check

# 2. Enable the toolset
hermes tools enable custom

# 3. Start a new session and test
hermes chat -q "Run a health check on all services"

# 4. The agent should call the health_check tool and report results

Next: Capstone: The Operations Console , building a complete Hermes-based operations dashboard.