Skip to content

fix(gateway): format scoped MCP server names during reload - #109483

Closed
luinbytes wants to merge 1 commit into
NousResearch:mainfrom
luinbytes:fix/gateway-mcp-reload-scoped-names
Closed

luinbytes wants to merge 1 commit into
NousResearch:mainfrom
luinbytes:fix/gateway-mcp-reload-scoped-names

Conversation

@luinbytes

Copy link
Copy Markdown

What does this PR do?

Fixes a gateway /reload-mcp crash when multiplexed MCP connections are keyed by (profile_scope, server_name) tuples.

_execute_mcp_reload() collects connection keys for its status summary, then passes them to ", ".join(...). With tuple keys, it returns MCP reload failed: sequence item 0: expected str instance, tuple found before reaching _mcp_reload_refresh_cached_agents().

Use the existing _key_name() accessor for display names, after filtering the original keys through _server_visible_in_scope(). This preserves profile scoping without stringifying internal tuples or changing connection ownership, discovery, or cache-refresh policy.

Related Issue

No separate issue found for this exact gateway crash. Follow-up to the composite connection keys introduced in #108352. The open reload-label PRs #94452 and #104051 concern configured-versus-connected diff semantics, not this tuple-formatting failure.

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)

Changes Made

  • gateway/run_turn.py: convert visible connection keys to server names through _key_name().
  • tests/gateway/test_multiplex_mcp_discovery.py: add one regression test using real tuple-shaped connection keys. Assert the requesting profile's name appears, a sibling profile's name does not, and cached-agent refresh is reached.

How to Test

Reproduction

  1. Run a multiplexed gateway with an MCP connection belonging to a secondary profile.
  2. Send /reload-mcp from that profile's gateway conversation.
  3. Before this fix, the status-summary join fails with the tuple TypeError, preventing cached-agent refresh. After this fix, the summary reports plain server names and the refresh path completes.

The automated regression exercises the real gateway handler and scope predicate with temporary profile homes; network discovery/shutdown and the refresh call are mocked. It is not a claim of a live-network end-to-end test.

Automated validation

Tested on macOS 15.7.7 against base de2d6a1b93508463c31434c1ae067e204af81238.

scripts/run_tests.sh tests/gateway/test_multiplex_mcp_discovery.py
# 9 passed
scripts/run_tests.sh tests/tools/test_mcp_multiplex_connection_keys.py
# 2 passed
scripts/run_tests.sh tests/tools/test_refresh_agent_mcp_tools.py
# 19 passed
python scripts/check-windows-footguns.py gateway/run_turn.py tests/gateway/test_multiplex_mcp_discovery.py
# No Windows footguns found
git diff --check
# Clean

The new regression was run before the production fix and failed with the exact reported error; it passes with the fix. All 30 focused tests pass using the canonical hermetic runner. The full repository suite and live-network manual reproduction have not been run for this PR.

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits
  • I searched for existing open and merged PRs and issues to make sure this isn't a duplicate
  • My PR contains only changes related to this fix, with no unrelated commits
  • I've run pytest tests/ -q and all tests pass (full suite not run; focused canonical-runner results above)
  • I've added tests for my changes
  • I've tested on my platform: macOS 15.7.7

Documentation & Housekeeping

  • Relevant documentation: N/A, restores existing behaviour
  • cli-config.yaml.example: N/A, no configuration changes
  • CONTRIBUTING.md / AGENTS.md: N/A, no architecture or workflow changes
  • Cross-platform impact considered: no new OS-specific operations; Windows-footgun check passes
  • Tool descriptions/schemas: N/A, unchanged

Screenshots / Logs

Before the production fix, the new regression reports:

MCP reload failed: sequence item 0: expected str instance, tuple found
1 failed

After the fix, the focused canonical-runner files report 9, 2, and 19 tests passed respectively, with no failures.

@gaoanze888 gaoanze888 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified exact head 3ca21d125c85d346c00cdd64a6b578950de70a83. Filtering the original scoped connection key before converting with _key_name() preserves profile isolation, handles legacy string keys, and prevents tuple values from reaching the display/sort/join path. Same-name connections remain isolated by their tuple keys before display normalization.

The focused multiplex discovery suite passes 9/9 with the async test dependency present; Ruff and diff checks are clean. I found no blocker in this narrowly scoped change. Residual risk is limited to the mocked process reconnect path; the changed production behavior is the three-line key-to-name projection after an existing visibility predicate.

@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/gateway Gateway runner, session dispatch, delivery tool/mcp MCP client and OAuth area/profiles Multi-profile isolation, HERMES_HOME scoping labels Sep 13, 2026
@rxShri99

Copy link
Copy Markdown

Thanks, it fixed the issue I was having.

@teknium1

Copy link
Copy Markdown
Collaborator

Thanks @luinbytes — landed on main via #110271 (merge 6636b0896c77). Your commit is on main as ed6f19f14fae with authorship preserved, taken as-is (correct, minimal, one test). It closes the _execute_mcp_reload tuple-key join that ehz0ah's review of #108352 reproduced (MCP reload failed: sequence item 0: expected str instance, tuple found). Closing in favour of the merged salvage.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/profiles Multi-profile isolation, HERMES_HOME scoping comp/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists tool/mcp MCP client and OAuth type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants