hermes - 💡(How to fix) Fix MCP `channels_list` always returns 0 channels — schema mismatch with `channel_directory.json`

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…

Root Cause

Schema mismatch between writer and reader.

Writergateway/channel_directory.py:99-102:

directory = {
    "updated_at": datetime.now().isoformat(),
    "platforms": platforms,   # {"discord": [...], "telegram": [...], ...}
}

Readermcp_serve.py:805:

for plat, entries_list in directory.items():
    ...
    if isinstance(entries_list, list):
        ...

Iterating directory.items() yields ("updated_at", str) and ("platforms", dict). Neither passes isinstance(entries_list, list), so the inner loop never runs.

The fallback-to-sessions branch at mcp_serve.py:780 (if not directory:) doesn't trigger because the file loads non-empty.

Every other reader in the codebase (gateway/channel_directory.py:261, 277, 317) correctly unwraps directory.get("platforms", {}). mcp_serve.channels_list is the only consumer with this bug.

Fix Action

Fix

--- a/mcp_serve.py
+++ b/mcp_serve.py
@@ -802,7 +802,7 @@ def create_mcp_server(event_bridge: Optional[EventBridge] = None) -> "FastMCP":
             return json.dumps({"count": len(targets), "channels": targets}, indent=2)

         channels = []
-        for plat, entries_list in directory.items():
+        for plat, entries_list in directory.get("platforms", {}).items():
             if platform and plat.lower() != platform.lower():
                 continue
             if isinstance(entries_list, list):

Code Example

directory = {
    "updated_at": datetime.now().isoformat(),
    "platforms": platforms,   # {"discord": [...], "telegram": [...], ...}
}

---

for plat, entries_list in directory.items():
    ...
    if isinstance(entries_list, list):
        ...

---

--- a/mcp_serve.py
+++ b/mcp_serve.py
@@ -802,7 +802,7 @@ def create_mcp_server(event_bridge: Optional[EventBridge] = None) -> "FastMCP":
             return json.dumps({"count": len(targets), "channels": targets}, indent=2)

         channels = []
-        for plat, entries_list in directory.items():
+        for plat, entries_list in directory.get("platforms", {}).items():
             if platform and plat.lower() != platform.lower():
                 continue
             if isinstance(entries_list, list):
RAW_BUFFERClick to expand / collapse

Bug

mcp_serve.channels_list returns {"count": 0, "channels": []} even when channel_directory.json is populated and the gateway has Discord/Slack/etc. connected.

Reproduce

  1. Run hermes mcp serve with at least one platform adapter connected.
  2. Wait for build_channel_directory to write ~/.hermes/channel_directory.json (gateway startup or 5-min refresh).
  3. From an MCP client, call channels_list.
  4. Result: {"count": 0, "channels": []} — despite the file containing populated platforms.

conversations_list works correctly; only channels_list is affected.

Root cause

Schema mismatch between writer and reader.

Writergateway/channel_directory.py:99-102:

directory = {
    "updated_at": datetime.now().isoformat(),
    "platforms": platforms,   # {"discord": [...], "telegram": [...], ...}
}

Readermcp_serve.py:805:

for plat, entries_list in directory.items():
    ...
    if isinstance(entries_list, list):
        ...

Iterating directory.items() yields ("updated_at", str) and ("platforms", dict). Neither passes isinstance(entries_list, list), so the inner loop never runs.

The fallback-to-sessions branch at mcp_serve.py:780 (if not directory:) doesn't trigger because the file loads non-empty.

Every other reader in the codebase (gateway/channel_directory.py:261, 277, 317) correctly unwraps directory.get("platforms", {}). mcp_serve.channels_list is the only consumer with this bug.

Fix

--- a/mcp_serve.py
+++ b/mcp_serve.py
@@ -802,7 +802,7 @@ def create_mcp_server(event_bridge: Optional[EventBridge] = None) -> "FastMCP":
             return json.dumps({"count": len(targets), "channels": targets}, indent=2)

         channels = []
-        for plat, entries_list in directory.items():
+        for plat, entries_list in directory.get("platforms", {}).items():
             if platform and plat.lower() != platform.lower():
                 continue
             if isinstance(entries_list, list):

Affected versions

Confirmed on origin/main at 62c2f5d8d2a6a21adfdea2d8d1f28fd8f04b5dd7.

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