{"repo":"NousResearch/hermes-agent","public_id":"2711","display_label":"Pre-compile and unify MCP env-var regex interpolation","summary":"These items all address the same change: pre-compiling the environment variable interpolation regex in MCP-related code and unifying that interpolation logic across relevant modules. The members appear to be duplicate or iterative versions of the same fix or refactor.","subsystem":"mcp","counts":{"members":4,"open_issues":0,"open_issues_distinct":0,"open_prs":0,"closed_issues":1,"merged_prs":1,"attempt_prs":2},"landed_fix":{"status":"merged_to_main","basis":"structural","pr":26240,"merged_at":"2026-05-15T08:43:55+00:00"},"resolution":{"state":"resolved","by":"pr-26240"},"freshness":{"state":"verified","last_verified_at":"2026-05-15T08:43:55+00:00","is_stale":false},"grouping":{"backbone":"STRUCTURAL_SPANNING","link_density":0.5},"fix_edges":[{"issue_number":2711,"pr_number":26240,"tier":"verified","basis":"closing_ref","confidence":0.95,"recoverable_from_timeline":true,"pr_merged_at":"2026-05-15T08:43:55+00:00"},{"issue_number":2712,"pr_number":26240,"tier":"verified","basis":"closing_ref","confidence":0.95,"recoverable_from_timeline":true,"pr_merged_at":"2026-05-15T08:43:55+00:00"}],"members":[{"kind":"issue","number":2711,"title":"Pre-compile env-var interpolation regex in mcp_tool.py","url":null,"state":"closed"},{"kind":"pr","number":2719,"title":"fix(mcp): pre-compile env-var regex and unify interpolation across mcp_tool and mcp_config","url":null,"state":"closed","close_reason":{"refs":[{"kind":"pr","value":"#26240","number":26240}],"category":"merged_via","implication":"superseded"},"merged":false},{"kind":"pr","number":2728,"title":"refactor(mcp): unify env-var interpolation and pre-compile regex","url":null,"state":"closed","close_reason":{"category":"uncategorized","implication":"needs_llm"},"merged":false,"is_fix_pr":true,"fix_tier":"suggested","fix_detail_withheld":true},{"kind":"pr","number":26240,"title":"fix(mcp): pre-compile env-var regex and unify interpolation","url":null,"state":"merged","close_reason":{"category":"merged"},"merged":true,"is_fix_pr":true,"fix_tier":"verified","files_changed":["hermes_cli/mcp_config.py","scripts/release.py","tools/mcp_tool.py"],"fix_hunks":[{"file":"hermes_cli/mcp_config.py","hunks":["@@ -25,6 +25,7 @@\n )\n from hermes_cli.colors import Colors, color\n from hermes_constants import display_hermes_home\n+from tools.mcp_tool import _ENV_VAR_PATTERN\n \n logger = logging.getLogger(__name__)\n ","@@ -551,7 +552,7 @@ def cmd_mcp_test(args):\n         for k, v in headers.items():\n             if isinstance(v, str) and (\"key\" in k.lower() or \"auth\" in k.lower()):\n                 # Mask the value\n-                resolved = _interpolate_value(v)\n+                resolved = _ENV_VAR_PATTERN.sub(lambda m: os.getenv(m.group(1), \"\"), v)\n                 if len(resolved) > 8:\n                     masked = resolved[:4] + \"***\" + resolved[-4:]\n                 else:","@@ -581,13 +582,6 @@ def cmd_mcp_test(args):\n     print()\n \n \n-def _interpolate_value(value: str) -> str:\n-    \"\"\"Resolve ``${ENV_VAR}`` references in a string.\"\"\"\n-    def _replace(m):\n-        return os.getenv(m.group(1), \"\")\n-    return re.sub(r\"\\$\\{(\\w+)\\}\", _replace, value)\n-\n-\n # ─── hermes mcp login ────────────────────────────────────────────────────────\n \n def cmd_mcp_login(args):"]},{"file":"scripts/release.py","hunks":["@@ -111,6 +111,7 @@\n     \"oswaldb22@users.noreply.github.com\": \"oswaldb22\",\n     \"[redacted:email]\": \"AJV20\",\n     \"[redacted:email]\": \"masonjames\",\n+    \"108541149+amethystani@users.noreply.github.com\": \"amethystani\",\n     \"[redacted:email]\": \"liquidchen\",\n     \"[redacted:email]\": \"subtract0\",\n     \"[redacted:email]\": \"ReqX\","]},{"file":"tools/mcp_tool.py","hunks":["@@ -279,6 +279,11 @@ def _check_message_handler_support() -> bool:\n     re.IGNORECASE,\n )\n \n+# Pre-compiled pattern for ${VAR_NAME} style env-var interpolation.\n+# Supports any non-} characters in the variable name (hyphens, dots, etc.)\n+# so providers like MY-VAR or my.var work correctly.\n+_ENV_VAR_PATTERN = re.compile(r\"\\$\\{([^}]+)\\}\")\n+\n \n # ---------------------------------------------------------------------------\n # Security helpers","@@ -2104,7 +2109,7 @@ def _interpolate_env_vars(value):\n     if isinstance(value, str):\n         def _replace(m):\n             return os.environ.get(m.group(1), m.group(0))\n-        return re.sub(r\"\\$\\{([^}]+)\\}\", _replace, value)\n+        return _ENV_VAR_PATTERN.sub(_replace, value)\n     if isinstance(value, dict):\n         return {k: _interpolate_env_vars(v) for k, v in value.items()}\n     if isinstance(value, list):\n"]}]}],"trust":{"default_tier":"verified","includes_suggested":false}}