hermes - 💡(How to fix) Fix [Bug]: [Bug] v0.13.0 — Native tools missing from all sessions, only MCP tools load

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

On Hermes v0.13.0, native tools (terminal, write_file, memory, send_message, web_search, etc.) never appear in the model's tool list during live gateway or CLI sessions. Only MCP server tools reach the model. This affects all providers tested (Claude Sonnet 4, Kimi K2.6, Gemini 2.5 Flash) and persists across gateway restarts, config changes, reinstalls, and source patches.

Standalone Python tests of the full get_tool_definitions() pipeline return 70 tools (28 native + 42 MCP) correctly. The live gateway and CLI runtime produce 42 MCP tools only in self.tools.


Error Message

| Fixed YAML indentation error at line 477 | Fixed config parsing but didn't restore tools |

Additional Logs / Traceback (optional)

Root Cause

Date: May 9, 2026 (updated after extended debugging session) Reporter: apache@MSI (Hermes user) Discord context: Seeking root cause + fix for production gateway

Fix Action

Fix / Workaround

On Hermes v0.13.0, native tools (terminal, write_file, memory, send_message, web_search, etc.) never appear in the model's tool list during live gateway or CLI sessions. Only MCP server tools reach the model. This affects all providers tested (Claude Sonnet 4, Kimi K2.6, Gemini 2.5 Flash) and persists across gateway restarts, config changes, reinstalls, and source patches.

ItemValue
Hermes versionv0.13.0 (2026.5.7), clean reinstall May 9
OSUbuntu 24.04.2 LTS
HostMSI GE72VR (home server, lid-closed, 24/7)
Userapache
Python3.11.15
Primary modelclaude-sonnet-4-6 via provider: anthropic
Fallback modelsgemini-2.5-flash
MCP serversobsidian (12 tools), gdrive (3 tools), notion (22 tools), tavily (5 tools) = 42 total
Telegram gatewayActive, systemd user service with linger
Install methodcurl installer (clean reinstall, no local patches)

Source patches (both applied, neither resolved the issue)

PatchLocationResult
Added discover_builtin_tools() before discover_mcp_tools() at gateway startupgateway/run.py line 15642No change — tools still absent
Added discover_builtin_tools() immediately before self.tools = get_tool_definitions()run_agent.py line 1757Terminal worked ONCE (single command), then stopped working in same session

Code Example

# Hermes v0.13.0 Bug ReportNative Tools Absent from Gateway & CLI Sessions

**Date:** May 9, 2026 (updated after extended debugging session)
**Reporter:** apache@MSI (Hermes user)
**Discord context:** Seeking root cause + fix for production gateway

---

## Summary

On Hermes v0.13.0, native tools (terminal, write_file, memory, send_message, web_search, etc.) never appear in the model's tool list during live gateway or CLI sessions. Only MCP server tools reach the model. This affects all providers tested (Claude Sonnet 4, Kimi K2.6, Gemini 2.5 Flash) and persists across gateway restarts, config changes, reinstalls, and source patches.

Standalone Python tests of the full `get_tool_definitions()` pipeline return **70 tools (28 native + 42 MCP)** correctly. The live gateway and CLI runtime produce **42 MCP tools only** in `self.tools`.

---

## Environment

| Item | Value |
|------|-------|
| Hermes version | v0.13.0 (2026.5.7), clean reinstall May 9 |
| OS | Ubuntu 24.04.2 LTS |
| Host | MSI GE72VR (home server, lid-closed, 24/7) |
| User | apache |
| Python | 3.11.15 |
| Primary model | claude-sonnet-4-6 via provider: anthropic |
| Fallback models | gemini-2.5-flash |
| MCP servers | obsidian (12 tools), gdrive (3 tools), notion (22 tools), tavily (5 tools) = 42 total |
| Telegram gateway | Active, systemd user service with linger |
| Install method | curl installer (clean reinstall, no local patches) |

---

## Symptom

When any model is asked to list its available tools in a Telegram or CLI session, the response contains **only MCP server tools**. Native Hermes tools are completely absent.

Session JSON confirms at the Python level — `self.tools` contains 42 MCP tools and zero native tools before any model API call is made.


# Latest session file check
python3 -c "
import json, sys, glob
latest = max(glob.glob('/home/apache/.hermes/sessions/session_20260509*.json'), key=lambda f: open(f).read()[:50])
data = json.load(open(latest))
tools = data.get('tools', [])
print(f'Tool count: {len(tools)}')
print('Has terminal:', any(t['function']['name']=='terminal' for t in tools))
print('Model:', data.get('model','?'))
print('Platform:', data.get('platform','?'))
"
# Output:
# Tool count: 42
# Has terminal: False
# Model: claude-sonnet-4-6
# Platform: telegram


---

## What We Verified Works Correctly (Isolation Tests)

Every component of the pipeline tests correctly in standalone Python:

### 1. Registry — native tools register correctly

from tools.registry import registry, discover_builtin_tools
discover_builtin_tools()
print('terminal registered:', 'terminal' in registry.get_all_tool_names())  # True
print('Total registered:', len(registry.get_all_tool_names()))  # 70


### 2. check_fn — terminal availability check passes

from tools.terminal_tool import check_terminal_requirements
print(check_terminal_requirements())  # True


### 3. _get_platform_tools — returns correct toolsets for telegram

import yaml
with open('/home/apache/.hermes/config.yaml') as f:
    config = yaml.safe_load(f)
from hermes_cli.tools_config import _get_platform_tools
result = _get_platform_tools(config, 'telegram')
print(sorted(result))
# terminal, file, memory, web, messaging, etc.  all present


### 4. get_tool_definitions — returns native tools correctly

from tools.registry import discover_builtin_tools
discover_builtin_tools()
from model_tools import get_tool_definitions
result = get_tool_definitions(['hermes-telegram'], [], quiet_mode=True)
print('count:', len(result))  # 28 native tools
print('terminal:', any(t['function']['name']=='terminal' for t in result))  # True


### 5. Full simulation with MCP tools — returns 70 tools

from tools.registry import registry, discover_builtin_tools
discover_builtin_tools()
# [simulate MCP registration as in previous report]
# Result: 70 tools, terminal present — confirmed correct


**The standalone pipeline is entirely correct. The failure is exclusively in the live runtime.**

---

## Configuration (Verified Correct)


model:
  default: claude-sonnet-4-6
  provider: anthropic

platform_toolsets:
  cli: [hermes-cli, terminal, file, memory]
  telegram: [hermes-telegram]

# hermes-telegram is a composite that resolves to ~22 individual toolsets
# including terminal, file, memory, web, messaging, session_search, etc.


YAML validation passes. Config loads correctly in standalone Python.

---

## What Was Tried and Failed

### Config fixes (all applied, none resolved the issue)
| Fix | Result |
|-----|--------|
| Changed `platform_toolsets.telegram` from explicit list to `[hermes-telegram]` composite | No change — 42 MCP tools only |
| Changed from `[browser, clarify]` (corrupted by Docker migration) to full toolset list | No change |
| Fixed YAML indentation error at line 477 | Fixed config parsing but didn't restore tools |
| Switched model from kimi-k2.6 to claude-sonnet-4-6 | Claude works but still 42 MCP tools only |
| Fixed Anthropic provider base_url (removed duplicate /v1) | Claude connects but tools unchanged |

### Source patches (both applied, neither resolved the issue)
| Patch | Location | Result |
|-------|----------|--------|
| Added `discover_builtin_tools()` before `discover_mcp_tools()` at gateway startup | gateway/run.py line 15642 | No change — tools still absent |
| Added `discover_builtin_tools()` immediately before `self.tools = get_tool_definitions()` | run_agent.py line 1757 | Terminal worked ONCE (single command), then stopped working in same session |

### Other attempts
| Action | Result |
|--------|--------|
| Multiple gateway restarts | No change |
| `/new` session resets | No change |
| Cleared Python bytecode cache (`__pycache__`) | No change |
| Nuked session store (`state.db`, `sessions.db`) | No change |
| `hermes tools enable terminal --platform telegram` | Added to config but tool still not loaded at runtime |
| Clean reinstall via `curl installer` | Installer detected existing install, did git pull, "Already up to date" |
| Reverted all local patches to vanilla v0.13.0 | No change — still 42 MCP tools |
| Tested across 3 different models (Claude, Kimi, Gemini) | All show same behavior |
| Tested CLI sessions (not just gateway/Telegram) | CLI sessions also missing native tools (47 tools = 42 MCP + 5 plugin, 0 native) |

---

## Probable Trigger Event

On May 7-8, Docker containers were launched via `docker-compose.yml` that bind-mounted `~/.hermes:/opt/data`. The Docker containers:

1. Ran as UID 10000 (not `apache`), changing file ownership across `~/.hermes/`
2. Ran their own gateway process which migrated `config.yaml` from version 2223
3. The config migration rewrote `platform_toolsets.telegram` from `[hermes-telegram]` to `[browser, clarify]`
4. May have corrupted other state files (state.db, sessions.db, gateway_state.json)

Docker containers were stopped and removed. File ownership was fixed with `chown -R`. Config was manually corrected. But native tools never recovered.

The v0.13.0 codebase was already on the machine before Docker. Cron sessions from May 7 (pre-Docker) show native tools working correctly (9 tools including terminal). The break occurred during/after the Docker deployment.

---

## Suspected Root Cause

The gap between standalone Python (70 tools) and live runtime (42 MCP only) persists even when `discover_builtin_tools()` is called immediately before `get_tool_definitions()`. This suggests:

1. `get_tool_definitions()` is being called with different arguments in the live runtime than in standalone tests
2. The `enabled_toolsets` parameter passed to `get_tool_definitions()` may not include native toolsets despite the config being correct
3. A corrupted state file or cache from the Docker deployment may be overriding the config-based toolset resolution
4. The config migration from v22 → v23 may have changed internal state beyond `platform_toolsets` that affects tool loading

The run_agent.py patch (adding `discover_builtin_tools()` at line 1757) produced one successful terminal execution before reverting to MCP-only behavior, suggesting a race condition or cache invalidation issue rather than a simple ordering bug.

---

## Diagnostic Commands for Nous Team


# Confirm tools in latest session log
python3 -c "
import json, glob
files = sorted(glob.glob('/home/apache/.hermes/sessions/session_20260509*.json'),
               key=lambda f: f.split('session_')[1])
latest = files[-1]
data = json.load(open(latest))
tools = data.get('tools', [])
print(f'Session: {latest}')
print(f'Tool count: {len(tools)}')
print('Has terminal:', any(t['function']['name']=='terminal' for t in tools))
print('Has write_file:', any(t['function']['name']=='write_file' for t in tools))
"

# Confirm standalone pipeline works
cd ~/.hermes/hermes-agent && venv/bin/python -c "
from tools.registry import registry, discover_builtin_tools
discover_builtin_tools()
print('Registry tools:', len(registry.get_all_tool_names()))
print('terminal:', 'terminal' in registry.get_all_tool_names())
from model_tools import get_tool_definitions
result = get_tool_definitions(['hermes-telegram'], [])
print('get_tool_definitions result:', len(result))
print('terminal in result:', any(t['function']['name']=='terminal' for t in result))
"

# Check config
grep -A 4 'platform_toolsets:' ~/.hermes/config.yaml


---

## Impact

- All native tools (terminal, write_file, read_file, memory, send_message, web_search, cronjob, etc.) are inaccessible in both gateway and CLI sessions
- Automated cron jobs relying on terminal for Gmail/Google API operations fail
- Interactive sessions have no shell execution capability
- Only MCP tools (Obsidian, GDrive, Notion, Tavily) and plugin tools (evey_*) function
- System has been non-functional for 24+ hours despite extensive debugging

---

apache@MSI:~$ # Gateway startup log
journalctl --user -u hermes-gateway -n 100 --no-pager -l > /tmp/gateway_log.txt

# Latest session file showing 42 tools
ls -t ~/.hermes/sessions/session_20260509*.json | head -1 | xargs cp -t /tmp/
apache@MSI:~$
RAW_BUFFERClick to expand / collapse

Bug Description

Bug report: Native tools (terminal, write_file, memory, send_message) absent from all gateway and CLI sessions on v0.13.0. Only MCP tools load. Standalone Python tests confirm full pipeline works (70 tools). Live runtime produces 42 MCP tools only. Triggered by Docker deployment that migrated config v22→v23. Config has been fixed and verified — issue persists in vanilla code. Full diagnostic attached.

Steps to Reproduce

Steps to Reproduce:

  1. Install Hermes v0.13.0 with MCP servers configured (obsidian, gdrive, notion, tavily)
  2. Start gateway via systemd (hermes gateway start)
  3. Open Telegram or CLI session
  4. Ask model to use terminal, write_file, or any native tool

Expected Behavior

Expected Behavior: Session should contain ~70 tools (28 native + 42 MCP). Terminal, write_file, memory, send_message all callable.

Actual Behavior

Actual Behavior: Session contains only 42 MCP tools. All native tools absent. Standalone Python test of same pipeline returns 70 tools correctly — failure is exclusively in live runtime.

Affected Component

Tools (terminal, file ops, web, code execution, etc.)

Messaging Platform (if gateway-related)

Telegram

Debug Report

# Hermes v0.13.0 Bug Report — Native Tools Absent from Gateway & CLI Sessions

**Date:** May 9, 2026 (updated after extended debugging session)
**Reporter:** apache@MSI (Hermes user)
**Discord context:** Seeking root cause + fix for production gateway

---

## Summary

On Hermes v0.13.0, native tools (terminal, write_file, memory, send_message, web_search, etc.) never appear in the model's tool list during live gateway or CLI sessions. Only MCP server tools reach the model. This affects all providers tested (Claude Sonnet 4, Kimi K2.6, Gemini 2.5 Flash) and persists across gateway restarts, config changes, reinstalls, and source patches.

Standalone Python tests of the full `get_tool_definitions()` pipeline return **70 tools (28 native + 42 MCP)** correctly. The live gateway and CLI runtime produce **42 MCP tools only** in `self.tools`.

---

## Environment

| Item | Value |
|------|-------|
| Hermes version | v0.13.0 (2026.5.7), clean reinstall May 9 |
| OS | Ubuntu 24.04.2 LTS |
| Host | MSI GE72VR (home server, lid-closed, 24/7) |
| User | apache |
| Python | 3.11.15 |
| Primary model | claude-sonnet-4-6 via provider: anthropic |
| Fallback models | gemini-2.5-flash |
| MCP servers | obsidian (12 tools), gdrive (3 tools), notion (22 tools), tavily (5 tools) = 42 total |
| Telegram gateway | Active, systemd user service with linger |
| Install method | curl installer (clean reinstall, no local patches) |

---

## Symptom

When any model is asked to list its available tools in a Telegram or CLI session, the response contains **only MCP server tools**. Native Hermes tools are completely absent.

Session JSON confirms at the Python level — `self.tools` contains 42 MCP tools and zero native tools before any model API call is made.


# Latest session file check
python3 -c "
import json, sys, glob
latest = max(glob.glob('/home/apache/.hermes/sessions/session_20260509*.json'), key=lambda f: open(f).read()[:50])
data = json.load(open(latest))
tools = data.get('tools', [])
print(f'Tool count: {len(tools)}')
print('Has terminal:', any(t['function']['name']=='terminal' for t in tools))
print('Model:', data.get('model','?'))
print('Platform:', data.get('platform','?'))
"
# Output:
# Tool count: 42
# Has terminal: False
# Model: claude-sonnet-4-6
# Platform: telegram


---

## What We Verified Works Correctly (Isolation Tests)

Every component of the pipeline tests correctly in standalone Python:

### 1. Registry — native tools register correctly

from tools.registry import registry, discover_builtin_tools
discover_builtin_tools()
print('terminal registered:', 'terminal' in registry.get_all_tool_names())  # True
print('Total registered:', len(registry.get_all_tool_names()))  # 70


### 2. check_fn — terminal availability check passes

from tools.terminal_tool import check_terminal_requirements
print(check_terminal_requirements())  # True


### 3. _get_platform_tools — returns correct toolsets for telegram

import yaml
with open('/home/apache/.hermes/config.yaml') as f:
    config = yaml.safe_load(f)
from hermes_cli.tools_config import _get_platform_tools
result = _get_platform_tools(config, 'telegram')
print(sorted(result))
# terminal, file, memory, web, messaging, etc. — all present


### 4. get_tool_definitions — returns native tools correctly

from tools.registry import discover_builtin_tools
discover_builtin_tools()
from model_tools import get_tool_definitions
result = get_tool_definitions(['hermes-telegram'], [], quiet_mode=True)
print('count:', len(result))  # 28 native tools
print('terminal:', any(t['function']['name']=='terminal' for t in result))  # True


### 5. Full simulation with MCP tools — returns 70 tools

from tools.registry import registry, discover_builtin_tools
discover_builtin_tools()
# [simulate MCP registration as in previous report]
# Result: 70 tools, terminal present — confirmed correct


**The standalone pipeline is entirely correct. The failure is exclusively in the live runtime.**

---

## Configuration (Verified Correct)


model:
  default: claude-sonnet-4-6
  provider: anthropic

platform_toolsets:
  cli: [hermes-cli, terminal, file, memory]
  telegram: [hermes-telegram]

# hermes-telegram is a composite that resolves to ~22 individual toolsets
# including terminal, file, memory, web, messaging, session_search, etc.


YAML validation passes. Config loads correctly in standalone Python.

---

## What Was Tried and Failed

### Config fixes (all applied, none resolved the issue)
| Fix | Result |
|-----|--------|
| Changed `platform_toolsets.telegram` from explicit list to `[hermes-telegram]` composite | No change — 42 MCP tools only |
| Changed from `[browser, clarify]` (corrupted by Docker migration) to full toolset list | No change |
| Fixed YAML indentation error at line 477 | Fixed config parsing but didn't restore tools |
| Switched model from kimi-k2.6 to claude-sonnet-4-6 | Claude works but still 42 MCP tools only |
| Fixed Anthropic provider base_url (removed duplicate /v1) | Claude connects but tools unchanged |

### Source patches (both applied, neither resolved the issue)
| Patch | Location | Result |
|-------|----------|--------|
| Added `discover_builtin_tools()` before `discover_mcp_tools()` at gateway startup | gateway/run.py line 15642 | No change — tools still absent |
| Added `discover_builtin_tools()` immediately before `self.tools = get_tool_definitions()` | run_agent.py line 1757 | Terminal worked ONCE (single command), then stopped working in same session |

### Other attempts
| Action | Result |
|--------|--------|
| Multiple gateway restarts | No change |
| `/new` session resets | No change |
| Cleared Python bytecode cache (`__pycache__`) | No change |
| Nuked session store (`state.db`, `sessions.db`) | No change |
| `hermes tools enable terminal --platform telegram` | Added to config but tool still not loaded at runtime |
| Clean reinstall via `curl installer` | Installer detected existing install, did git pull, "Already up to date" |
| Reverted all local patches to vanilla v0.13.0 | No change — still 42 MCP tools |
| Tested across 3 different models (Claude, Kimi, Gemini) | All show same behavior |
| Tested CLI sessions (not just gateway/Telegram) | CLI sessions also missing native tools (47 tools = 42 MCP + 5 plugin, 0 native) |

---

## Probable Trigger Event

On May 7-8, Docker containers were launched via `docker-compose.yml` that bind-mounted `~/.hermes:/opt/data`. The Docker containers:

1. Ran as UID 10000 (not `apache`), changing file ownership across `~/.hermes/`
2. Ran their own gateway process which migrated `config.yaml` from version 2223
3. The config migration rewrote `platform_toolsets.telegram` from `[hermes-telegram]` to `[browser, clarify]`
4. May have corrupted other state files (state.db, sessions.db, gateway_state.json)

Docker containers were stopped and removed. File ownership was fixed with `chown -R`. Config was manually corrected. But native tools never recovered.

The v0.13.0 codebase was already on the machine before Docker. Cron sessions from May 7 (pre-Docker) show native tools working correctly (9 tools including terminal). The break occurred during/after the Docker deployment.

---

## Suspected Root Cause

The gap between standalone Python (70 tools) and live runtime (42 MCP only) persists even when `discover_builtin_tools()` is called immediately before `get_tool_definitions()`. This suggests:

1. `get_tool_definitions()` is being called with different arguments in the live runtime than in standalone tests
2. The `enabled_toolsets` parameter passed to `get_tool_definitions()` may not include native toolsets despite the config being correct
3. A corrupted state file or cache from the Docker deployment may be overriding the config-based toolset resolution
4. The config migration from v22 → v23 may have changed internal state beyond `platform_toolsets` that affects tool loading

The run_agent.py patch (adding `discover_builtin_tools()` at line 1757) produced one successful terminal execution before reverting to MCP-only behavior, suggesting a race condition or cache invalidation issue rather than a simple ordering bug.

---

## Diagnostic Commands for Nous Team


# Confirm tools in latest session log
python3 -c "
import json, glob
files = sorted(glob.glob('/home/apache/.hermes/sessions/session_20260509*.json'),
               key=lambda f: f.split('session_')[1])
latest = files[-1]
data = json.load(open(latest))
tools = data.get('tools', [])
print(f'Session: {latest}')
print(f'Tool count: {len(tools)}')
print('Has terminal:', any(t['function']['name']=='terminal' for t in tools))
print('Has write_file:', any(t['function']['name']=='write_file' for t in tools))
"

# Confirm standalone pipeline works
cd ~/.hermes/hermes-agent && venv/bin/python -c "
from tools.registry import registry, discover_builtin_tools
discover_builtin_tools()
print('Registry tools:', len(registry.get_all_tool_names()))
print('terminal:', 'terminal' in registry.get_all_tool_names())
from model_tools import get_tool_definitions
result = get_tool_definitions(['hermes-telegram'], [])
print('get_tool_definitions result:', len(result))
print('terminal in result:', any(t['function']['name']=='terminal' for t in result))
"

# Check config
grep -A 4 'platform_toolsets:' ~/.hermes/config.yaml


---

## Impact

- All native tools (terminal, write_file, read_file, memory, send_message, web_search, cronjob, etc.) are inaccessible in both gateway and CLI sessions
- Automated cron jobs relying on terminal for Gmail/Google API operations fail
- Interactive sessions have no shell execution capability
- Only MCP tools (Obsidian, GDrive, Notion, Tavily) and plugin tools (evey_*) function
- System has been non-functional for 24+ hours despite extensive debugging

Operating System

Ubuntu 24.04.4 LTS

Python Version

3.11.15

Hermes Version

v0.13.0

Additional Logs / Traceback (optional)

apache@MSI:~$ # Gateway startup log
journalctl --user -u hermes-gateway -n 100 --no-pager -l > /tmp/gateway_log.txt

# Latest session file showing 42 tools
ls -t ~/.hermes/sessions/session_20260509*.json | head -1 | xargs cp -t /tmp/
apache@MSI:~$

Root Cause Analysis (optional)

Docker containers (UID 10000) bind-mounted ~/.hermes and ran their own gateway, migrating config v22→v23 and corrupting platform_toolsets. Config was manually corrected and verified, but native tools still fail to load in live sessions. Standalone Python tests of the full tool pipeline (discover_builtin_tools → get_tool_definitions) return 70 tools correctly. The live gateway/CLI runtime returns only MCP tools. Root cause appears to be in the runtime initialization path — possibly get_tool_definitions() receiving wrong enabled_toolsets at session creation, or a corrupted state file overriding config-based toolset resolution.

Proposed Fix (optional)

Investigate the runtime path from config load → enabled_toolsets resolution → get_tool_definitions() in live gateway sessions. Standalone, this pipeline works correctly. In the gateway, the same pipeline produces MCP-only results. A patch adding discover_builtin_tools() immediately before self.tools = get_tool_definitions() in run_agent.py line 1757 produced one successful terminal execution before reverting to MCP-only, suggesting a race condition or cache invalidation issue. Additionally, consider adding a guard to prevent Docker-mediated config migrations from silently rewriting platform_toolsets — this was the initial trigger that started the cascade.

Are you willing to submit a PR for this?

  • I'd like to fix this myself and submit a PR

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING