fix: normalize numeric MCP server names to str (fixes #6901)
YAML parses bare numeric keys (e.g. `12306:`) as int, causing TypeError when sorted() is called on mixed int/str collections. Changes: - Normalize toolset_names entries to str in _get_platform_tools() - Cast MCP server name to str(name) when building enabled_mcp_servers - Add regression test
This commit is contained in:
@@ -509,6 +509,10 @@ def _get_platform_tools(
|
|||||||
default_ts = PLATFORMS[platform]["default_toolset"]
|
default_ts = PLATFORMS[platform]["default_toolset"]
|
||||||
toolset_names = [default_ts]
|
toolset_names = [default_ts]
|
||||||
|
|
||||||
|
# YAML may parse bare numeric names (e.g. ``12306:``) as int.
|
||||||
|
# Normalise to str so downstream sorted() never mixes types.
|
||||||
|
toolset_names = [str(ts) for ts in toolset_names]
|
||||||
|
|
||||||
configurable_keys = {ts_key for ts_key, _, _ in CONFIGURABLE_TOOLSETS}
|
configurable_keys = {ts_key for ts_key, _, _ in CONFIGURABLE_TOOLSETS}
|
||||||
|
|
||||||
# If the saved list contains any configurable keys directly, the user
|
# If the saved list contains any configurable keys directly, the user
|
||||||
@@ -567,7 +571,7 @@ def _get_platform_tools(
|
|||||||
# Special sentinel: "no_mcp" in the toolset list disables all MCP servers.
|
# Special sentinel: "no_mcp" in the toolset list disables all MCP servers.
|
||||||
mcp_servers = config.get("mcp_servers") or {}
|
mcp_servers = config.get("mcp_servers") or {}
|
||||||
enabled_mcp_servers = {
|
enabled_mcp_servers = {
|
||||||
name
|
str(name)
|
||||||
for name, server_cfg in mcp_servers.items()
|
for name, server_cfg in mcp_servers.items()
|
||||||
if isinstance(server_cfg, dict)
|
if isinstance(server_cfg, dict)
|
||||||
and _parse_enabled_flag(server_cfg.get("enabled", True), default=True)
|
and _parse_enabled_flag(server_cfg.get("enabled", True), default=True)
|
||||||
|
|||||||
@@ -428,3 +428,31 @@ class TestPlatformToolsetConsistency:
|
|||||||
f"Platform {platform!r} in tools_config but missing from "
|
f"Platform {platform!r} in tools_config but missing from "
|
||||||
f"skills_config PLATFORMS"
|
f"skills_config PLATFORMS"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_numeric_mcp_server_name_does_not_crash_sorted():
|
||||||
|
"""YAML parses bare numeric keys (e.g. ``12306:``) as int.
|
||||||
|
|
||||||
|
_get_platform_tools must normalise them to str so that sorted()
|
||||||
|
on the returned set never raises TypeError on mixed int/str.
|
||||||
|
|
||||||
|
Regression test for https://github.com/NousResearch/hermes-agent/issues/6901
|
||||||
|
"""
|
||||||
|
config = {
|
||||||
|
"platform_toolsets": {"cli": ["web", 12306]},
|
||||||
|
"mcp_servers": {
|
||||||
|
12306: {"url": "https://example.com/mcp"},
|
||||||
|
"normal-server": {"url": "https://example.com/mcp2"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
enabled = _get_platform_tools(config, "cli")
|
||||||
|
|
||||||
|
# All names must be str — no int leaking through
|
||||||
|
assert all(isinstance(name, str) for name in enabled), (
|
||||||
|
f"Non-string toolset names found: {enabled}"
|
||||||
|
)
|
||||||
|
assert "12306" in enabled
|
||||||
|
|
||||||
|
# sorted() must not raise TypeError
|
||||||
|
sorted(enabled)
|
||||||
|
|||||||
Reference in New Issue
Block a user