Summary
External skills are visible to Hermes/CLI and can be invoked by the agent, but they are excluded from Telegram slash command registration.
What I expected
Skills declared through skills.external_dirs should be eligible for Telegram slash command registration the same way bundled local skills are, subject to the same Telegram command cap and disabled-skill rules.
What happens
External skills appear in:
hermes skills list
get_skill_commands()
- normal CLI / agent skill usage
But they do not appear in Telegram getMyCommands.
Reproduction
- Configure an external skills directory, for example in
config.yaml:
skills:
external_dirs:
- ~/my-skills
- Add a valid external skill such as:
~/my-skills/morning-briefing/SKILL.md
- Confirm Hermes sees it:
hermes skills list
get_skill_commands() includes /morning-briefing
- Check Telegram Bot API
getMyCommands.
Observed results
- Hermes sees the skill
get_skill_commands() contains it
- its
skill_md_path is an external path such as:
/home/coder/my-skills/morning-briefing/SKILL.md
- Telegram
getMyCommands does not include /morning_briefing
Code evidence
In hermes_cli/commands.py, _collect_gateway_skill_entries() filters skills like this:
_skills_dir = str(SKILLS_DIR.resolve())
...
skill_path = info.get("skill_md_path", "")
if not skill_path.startswith(_skills_dir):
continue
That means only skills physically under SKILLS_DIR are eligible for gateway slash command registration.
External skills from skills.external_dirs are therefore excluded by path, even though they are present in get_skill_commands() and usable elsewhere.
Why this seems unintended / limiting
The user-facing skill system already treats external skills as first-class in CLI/tooling, so Telegram slash commands become inconsistent with the rest of Hermes.
Workaround that worked locally
A custom Telegram menu builder that:
- keeps the normal core/plugin ordering
- keeps hub skills excluded
- applies the same Telegram sanitization and cap logic
- but includes external skills from
get_skill_commands()
allowed /morning_briefing to appear in Telegram getMyCommands for all tested bots.
Version
Observed on nousresearch/hermes-agent:v2026.4.8.
Summary
External skills are visible to Hermes/CLI and can be invoked by the agent, but they are excluded from Telegram slash command registration.
What I expected
Skills declared through
skills.external_dirsshould be eligible for Telegram slash command registration the same way bundled local skills are, subject to the same Telegram command cap and disabled-skill rules.What happens
External skills appear in:
hermes skills listget_skill_commands()But they do not appear in Telegram
getMyCommands.Reproduction
config.yaml:~/my-skills/morning-briefing/SKILL.mdhermes skills listget_skill_commands()includes/morning-briefinggetMyCommands.Observed results
get_skill_commands()contains itskill_md_pathis an external path such as:/home/coder/my-skills/morning-briefing/SKILL.mdgetMyCommandsdoes not include/morning_briefingCode evidence
In
hermes_cli/commands.py,_collect_gateway_skill_entries()filters skills like this:That means only skills physically under
SKILLS_DIRare eligible for gateway slash command registration.External skills from
skills.external_dirsare therefore excluded by path, even though they are present inget_skill_commands()and usable elsewhere.Why this seems unintended / limiting
The user-facing skill system already treats external skills as first-class in CLI/tooling, so Telegram slash commands become inconsistent with the rest of Hermes.
Workaround that worked locally
A custom Telegram menu builder that:
get_skill_commands()allowed
/morning_briefingto appear in TelegramgetMyCommandsfor all tested bots.Version
Observed on
nousresearch/hermes-agent:v2026.4.8.