# NousResearch/hermes-agent · Strip blocked tools from delegated child agents

## Open now

- Nothing open on GitHub.

These issues and PRs concern a bug where delegated child agents incorrectly inherit messaging and cronjob toolsets despite those tools being blocked. The work involves fixing tool-stripping logic and removing the agent-callable send_message tool.

## TL;DR

- 5 member(s): 0 open issue(s), 1 closed issue(s), 0 open PR(s), 2 merged PR(s), 2 PR(s) closed without merging.
- A fix was merged to main in PR #47856. Verify it addresses your case.
- **Recommended:** read PR #47856 (and any competing PRs below) before filing. Confirm the merged change covers your symptom.

## Maintainer resolution verdict

- Internal-tracker verdict over this cluster's issue members: `resolved` · deciding PR(s): `pr-52121`. This is distinct from the fix status above. Weigh it yourself.

## How this cluster was grouped

- Link evidence (`STRUCTURAL_SPANNING`): every member is connected by structural evidence: shared changed files, or a closing/superseded reference.
- Pairwise link density `0.40`: the share of member pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36. `1.00` means every pair is linked.

## Closed / duplicate issues

- #43466: delegate_task: _strip_blocked_tools doesn't strip 'messaging'/'cronjob', so children inherit send_message and cronjob despite DELEGATE_BLOCKED_TOOLS

## Prior & competing PRs

- **#43687: fix(delegate): strip messaging and cronjob toolsets from child agents**. closed without merge · fix tier `suggested`
  - maintainer direction: category `superseded_by_pr`; implication `superseded`; refs `#43474`, `#43474`
  - _suggested-tier fix detail withheld; re-request with `?tier=all` to include it._
- **#47856: refactor: remove agent-callable send_message tool**. merged to main · fix tier `verified`
  - maintainer direction: category `merged`; implication `superseded`
  - files: `gateway/session.py`, `hermes_cli/tools_config.py`, `tests/hermes_cli/test_tools_config.py`, `tests/tools/test_mcp_tool.py`, `tools/mcp_tool.py`, `tools/send_message_tool.py`, `toolsets.py`, `website/docs/reference/mcp-config-reference.md`
  - fix hunks:
  - `gateway/session.py`

    ```diff
    @@ -386,9 +386,10 @@ def build_session_context_prompt(
             lines.append("")
             lines.append(
                 "**Platform notes:** You are running inside Yuanbao. "
    -            "You CAN send private (DM) messages via the send_message tool. "
    -            "Use target='yuanbao:direct:<account_id>' for DM "
    -            "and target='yuanbao:group:<group_code>' for group chat."
    +            "To send a private (DM) message to a user in the current group, "
    +            "use the yb_send_dm tool (look up the recipient by name or pass "
    +            "their user_id). Your normal reply is delivered to the group you "
    +            "are responding in."
             )
     
         # Connected platforms
    ```
  - `hermes_cli/tools_config.py`

    ```diff
    @@ -73,7 +73,6 @@
         ("clarify",         "❓ Clarifying Questions",      "clarify"),
         ("delegation",      "👥 Task Delegation",           "delegate_task"),
         ("cronjob",         "⏰ Cron Jobs",                 "create/list/update/pause/resume/run, with optional attached skills"),
    -    ("messaging",       "📨 Cross-Platform Messaging",  "send_message"),
         ("homeassistant",    "🏠 Home Assistant",           "smart home device control"),
         ("spotify",          "🎵 Spotify",                  "playback, search, playlists, library"),
         ("discord",         "💬 Discord (read/participate)", "fetch messages, search members, create thread"),
    ```
  - `tests/hermes_cli/test_tools_config.py`

    ```diff
    @@ -87,10 +87,6 @@ def test_gui_toolset_label_strips_leading_emoji():
         assert gui_toolset_label("Terminal & Processes") == "Terminal & Processes"
     
     
    -def test_configurable_toolsets_include_messaging():
    -    assert any(ts_key == "messaging" for ts_key, _, _ in CONFIGURABLE_TOOLSETS)
    -
    -
     def test_configurable_toolsets_include_context_engine():
         assert any(ts_key == "context_engine" for ts_key, _, _ in CONFIGURABLE_TOOLSETS)
     
    ```

    ```diff
    @@ -130,12 +126,6 @@ def test_get_platform_tools_context_engine_respects_explicit_empty_selection():
         assert "context_engine" not in enabled
     
     
    -def test_get_platform_tools_default_telegram_includes_messaging():
    -    enabled = _get_platform_tools({}, "telegram")
    -
    -    assert "messaging" in enabled
    -
    -
     def test_get_platform_tools_default_whatsapp_includes_web():
         enabled = _get_platform_tools({}, "whatsapp")
     
    ```
  - `tests/tools/test_mcp_tool.py`

    ```diff
    @@ -1884,7 +1884,7 @@ def test_default_timeout(self):
     
             server = MCPServerTask("test_srv")
             assert server.tool_timeout == _DEFAULT_TOOL_TIMEOUT
    -        assert server.tool_timeout == 120
    +        assert server.tool_timeout == 300
     
         def test_custom_timeout(self):
             """Server with timeout=180 in config gets 180."""
    ```
  - `tools/mcp_tool.py`

    ```diff
    @@ -17,7 +17,7 @@
             command: "npx"
             args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
             env: {}
    -        timeout: 120         # per-tool-call timeout in seconds (default: 120)
    +        timeout: 120         # per-tool-call timeout in seconds (default: 300)
             connect_timeout: 60  # initial connection timeout (default: 60)
           github:
             command: "npx"
    ```

    ```diff
    @@ -258,7 +258,7 @@ def _check_message_handler_support() -> bool:
     # Constants
     # ---------------------------------------------------------------------------
     
    -_DEFAULT_TOOL_TIMEOUT = 120      # seconds for tool calls
    +_DEFAULT_TOOL_TIMEOUT = 300      # seconds for tool calls
     _DEFAULT_CONNECT_TIMEOUT = 60    # seconds for initial connection per server
     _MAX_RECONNECT_RETRIES = 5
     _MAX_INITIAL_CONNECT_RETRIES = 3 # retries for the very first connection attempt
    ```
  - `tools/send_message_tool.py`

    ```diff
    @@ -1899,13 +1899,16 @@ async def _send_yuanbao(chat_id, message, media_files=None):
     
     
     # --- Registry ---
    -from tools.registry import registry, tool_error
    -
    -registry.register(
    -    name="send_message",
    -    toolset="messaging",
    -    schema=SEND_MESSAGE_SCHEMA,
    -    handler=send_message_tool,
    -    check_fn=_check_send_message,
    -    emoji="📨",
    -)
    +from tools.registry import tool_error
    +
    +# NOTE: ``send_message`` is intentionally NOT registered as an agent-callable
    +# model tool. The agent should not decide on its own to fire off cross-platform
    +# messages or reactions. The send engine in this module (``_send_to_platform``,
    +# ``_send_via_adapter``, ``_parse_target_ref``, the per-platform ``_send_*``
    +# helpers) remains the shared transport used by:
    +#   - cron delivery (cron/scheduler.py)
    +#   - the ``hermes send`` CLI command (hermes_cli/send_cmd.py)
    +#   - the gateway kanban notifier (dashboard-toggled, outside agent control)
    +#   - the standalone MCP server (mcp_serve.py), which is an opt-in surface
    +# Those callers import the helpers directly; none of them need the registry
    +# entry.
    ```
  - `toolsets.py`

    ```diff
    @@ -59,8 +59,6 @@
         "execute_code", "delegate_task",
         # Cronjob management
         "cronjob",
    -    # Cross-platform messaging (gated on gateway running via check_fn)
    -    "send_message",
         # Home Assistant smart home control (gated on HASS_TOKEN via check_fn)
         "ha_list_entities", "ha_get_state", "ha_list_services", "ha_call_service",
         # Kanban multi-agent coordination — only in schema when the agent is
    ```

    ```diff
    @@ -188,13 +186,7 @@
             "includes": []
         },
         
    -    "messaging": {
    -        "description": "Cross-platform messaging: send messages to Telegram, Discord, Slack, SMS, etc.",
    -        "tools": ["send_message"],
    -        "includes": []
    -    },
     
    -    
         "file": {
             "description": "File manipulation tools: read, write, patch (with fuzzy matching), and search (content + files)",
             "tools": ["read_file", "write_file", "patch", "search_files"],
    ```

    ```diff
    @@ -370,8 +362,10 @@
         # ==========================================================================
         # Full Hermes toolsets (CLI + messaging platforms)
         #
    -    # All platforms share the same core tools (including send_message,
    -    # which is gated on gateway running via its check_fn).
    +    # All platforms share the same core tools. Note: agents do NOT get an
    +    # agent-callable send_message tool — outbound platform messaging is handled
    +    # outside the agent loop (cron delivery, the gateway kanban notifier, and
    +    # the `hermes send` CLI), not by the model deciding to send on its own.
         # ==========================================================================
     
         "hermes-acp": {
    ```
  - `website/docs/reference/mcp-config-reference.md`

    ```diff
    @@ -54,8 +54,8 @@ mcp_servers:
     | `client_cert` | string or list | HTTP | mTLS client certificate. String = path to a PEM file containing cert + key. List `[cert, key]` = separate files. List `[cert, key, password]` = encrypted key |
     | `client_key` | string | HTTP | Path to the client private key, when `client_cert` is a string and the key is in a separate file |
     | `enabled` | bool | both | Skip the server entirely when false |
    -| `timeout` | number | both | Tool call timeout |
    -| `connect_timeout` | number | both | Initial connection timeout |
    +| `timeout` | number | both | Tool call timeout in seconds (default: `300`) |
    +| `connect_timeout` | number | both | Initial connection timeout in seconds (default: `60`) |
     | `supports_parallel_tool_calls` | bool | both | Allow tools from this server to run concurrently |
     | `tools` | mapping | both | Filtering and utility-tool policy |
     | `auth` | string | HTTP | Authentication method. Set to `oauth` to enable OAuth 2.1 with PKCE |
    ```
- **#52121: fix(delegate): strip cronjob toolset from delegated children (#43466)**. merged to main · fix tier `verified`
  - maintainer direction: category `merged`; implication `superseded`
  - files: `scripts/release.py`, `tests/tools/test_delegate.py`, `tools/delegate_tool.py`
- **#43474: fix(agent): strip messaging and cronjob toolsets from delegated children**. closed without merge
  - maintainer direction: category `implemented_elsewhere`; implication `superseded`; refs `#47856`, `#43466`

## Fix status

- Merged to main in PR #47856 (cited above). No release data is tracked. Verify downstream.
- Fix last verified (merged) `2026-06-24`.
- Subsystem: `agent`
