Skip to content

Feature: Custom tool overrides via ~/.hermes/custom_tools/ #11049

@iRonin

Description

@iRonin

Issue: Allow custom tool implementations without modifying core source

Problem

Users who want to replace or extend Hermes tool implementations (browser tools,
web tools, terminal backends, etc.) must modify files in tools/. This creates:

  • Merge conflicts on every hermes-update.sh --reinstall
  • Fork dependency — custom features can't be shared without forking
  • Broken plugin model — skills and context engines are already pluggable,
    but tools are not

Multiple users have already built custom browser backends (headed Chrome CDP,
Camofox, alternative automation frameworks) that all require patching
tools/browser_tool.py.

Proposed Solution

Add a ~/.hermes/custom_tools/ directory that Hermes scans at startup.
Any .py file whose module name matches a built-in tool (e.g. browser_tool)
overrides the built-in implementation. New files add new tools.

~/.hermes/custom_tools/
├── browser_tool.py      # Overrides built-in browser tools
├── web_tools.py         # Overrides web search/extract
└── my_tool.py           # Adds a new custom tool

This requires ~30 lines in tools/registry.py and is fully backwards compatible.

Benefits

  • Zero core modifications needed for custom tool implementations
  • Survives hermes-update.sh --reinstall
  • Custom tools are shareable (pip packages, git repos, .py files)
  • Consistent with existing skill and context engine plugin patterns
  • No breaking changes — directory is optional, defaults to no-op

Use Cases

  • Headed Chrome CDP browser automation (replace headless Chromium)
  • Alternative search backends (custom search APIs, local indexes)
  • Custom terminal backends (specialized execution environments)
  • Domain-specific tools (finance, legal, scientific data extraction)

Implementation

PR ready: ironin/tool-override-plugin branch with:

  • tools/custom_tools_loader.py — directory scanning + import with override patch
  • tools/registry.py — add override=True param to register()
  • model_tools.py — call custom tools loader after built-in discovery
  • Docs page: website/docs/user-guide/advanced/custom-tools.md

Related Issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Low — cosmetic, nice to havecomp/toolsTool registry, model_tools, toolsetstype/featureNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions