zapabob
e55ddc3e33
fix(mcp): suppress interactive OAuth stdin prompts during background discovery ( #35927 )
...
When an MCP server requires OAuth, the interactive `hermes` TUI froze on
startup: background MCP discovery hit the OAuth flow, which on an interactive
TTY spawns a daemon thread doing a blocking `sys.stdin.readline()` (the
"paste the redirect URL" fallback in mcp_oauth._wait_for_callback). That
thread competes with the TUI's own stdin reader for the same terminal, so
keystrokes get swallowed and the TUI appears frozen (up to the 300s OAuth
timeout). Reported symptom: "MCP OAuth: authorization required / Open this URL
... the tui is freezing, not respond to typing."
Add a thread-local `suppress_interactive_oauth()` context manager in
tools/mcp_oauth.py; `_is_interactive()` returns False while it's active, so the
stdin paste-thread and prompt are never created. Background discovery
(hermes_cli/mcp_startup.py, tui_gateway/entry.py) now runs discovery inside
that context, so OAuth-requiring servers soft-skip (raise
OAuthNonInteractiveError, already handled) instead of stealing the TUI's stdin.
A real `hermes mcp login` on the main thread is unaffected (thread-local).
Salvaged from #35945 by @zapabob (authorship preserved via cherry-pick;
resolved a conflict against main's new mcp_discovery_timeout / wait_for_mcp_
discovery refactor, keeping both). Verified E2E: with suppression the paste
prompt is NOT printed and no stdin thread spawns (raises OAuthNonInteractive
soft-skip); without it the prompt shows (the freeze). Mutation-verified
(removing the suppress check in _is_interactive fails the regression test).
76 tests pass, ruff clean.
Closes #35927 .
SELF-REVIEW FIX: the original #35945 used threading.local(), which does NOT
propagate to the dedicated mcp-event-loop thread where OAuth actually runs
(discover_mcp_tools dispatches the connect via run_coroutine_threadsafe), so
the suppression was a NO-OP in production (the tests passed only by stubbing
out the cross-thread dispatch). Converted to a contextvars.ContextVar, which
asyncio copies onto the scheduled coroutine — empirically verified suppression
now holds on the mcp-event-loop thread through the real _run_on_mcp_loop path.
Added a cross-thread regression test (fails on threading.local, passes on the
ContextVar) so the no-op can't regress.
2026-06-27 04:59:23 +05:30
..
2026-05-22 03:33:01 -07:00
2026-05-28 22:26:25 -07:00
2026-05-28 22:26:25 -07:00
2026-06-21 13:33:48 -07:00
2026-05-28 22:26:25 -07:00
2026-06-26 11:38:28 -07:00
2026-06-20 11:27:12 -07:00
2026-05-28 22:26:25 -07:00
2026-06-11 10:49:47 -07:00
2026-05-12 15:14:49 -07:00
2026-05-28 22:26:25 -07:00
2026-06-25 22:02:22 -07:00
2026-04-17 16:05:04 -07:00
2026-04-24 03:46:46 -07:00
2026-05-28 22:26:25 -07:00
2026-05-28 22:26:25 -07:00
2026-05-09 13:35:39 -07:00
2026-05-29 03:58:56 -07:00
2026-05-28 22:26:25 -07:00
2026-05-30 07:31:25 -07:00
2026-06-24 00:14:49 -07:00
2026-06-24 00:14:49 -07:00
2026-04-26 09:57:58 -07:00
2026-05-06 03:41:21 -07:00
2026-06-21 15:23:47 -07:00
2026-06-07 11:42:26 -06:00
2026-06-21 07:26:18 -07:00
2026-04-30 20:33:33 -07:00
2026-05-28 22:26:25 -07:00
2026-06-25 22:02:22 -07:00
2026-06-21 17:46:38 +05:30
2026-05-28 22:26:25 -07:00
2026-05-28 22:26:25 -07:00
2026-06-19 06:31:08 -07:00
2026-05-28 22:26:25 -07:00
2026-05-17 02:29:41 -07:00
2026-05-29 03:44:49 -07:00
2026-06-21 16:55:12 -07:00
2026-06-18 12:48:36 +10:00
2026-06-22 06:42:30 -07:00
2026-06-07 02:09:20 -07:00
2026-06-22 18:48:07 -05:00
2026-05-28 22:26:25 -07:00
2026-06-25 02:33:40 +00:00
2026-06-27 04:57:15 +05:30
2026-05-08 14:55:40 -07:00
2026-05-28 22:26:25 -07:00
2026-06-26 01:11:11 -07:00
2026-06-21 13:28:04 +05:30
2026-06-23 23:27:48 -07:00
2026-05-28 22:26:25 -07:00
2026-05-28 22:26:25 -07:00
2026-05-28 22:26:25 -07:00
2026-06-16 14:30:11 -04:00
2026-05-28 22:26:25 -07:00
2026-06-27 03:59:36 +05:30
2026-05-28 22:26:25 -07:00
2026-06-24 15:23:23 +10:00
2026-06-08 22:46:57 -07:00
2026-05-29 11:49:54 +10:00
2026-06-25 09:20:13 +10:00
2026-06-18 09:09:21 +10:00
2026-06-10 19:23:06 +10:00
2026-05-28 22:26:25 -07:00
2026-05-28 22:26:09 -07:00
2026-06-04 19:40:30 -07:00
2026-04-17 19:04:11 -07:00
2026-05-30 07:01:22 -07:00
2026-06-17 13:45:25 -07:00
2026-05-28 22:26:25 -07:00
2026-06-21 12:16:10 -07:00
2026-04-23 15:11:52 -07:00
2026-04-21 16:41:26 -07:00
2026-05-28 22:26:25 -07:00
2026-06-15 14:00:42 +05:30
2026-06-25 16:40:27 -05:00
2026-05-28 22:26:25 -07:00
2026-06-23 03:17:47 +05:30
2026-06-21 11:55:59 -07:00
2026-06-27 04:01:12 +05:30
2026-06-26 20:45:32 +05:30
2026-06-26 01:55:27 +05:30
2026-06-01 16:55:04 -07:00
2026-05-28 22:26:25 -07:00
2026-05-28 22:26:25 -07:00
2026-05-28 22:26:25 -07:00
2026-05-21 16:40:04 +05:30
2026-06-18 22:13:07 -07:00
2026-05-15 01:33:13 -07:00
2026-06-19 16:59:54 -07:00
2026-04-23 03:01:18 -07:00
2026-06-25 12:38:33 -07:00
2026-04-28 22:16:08 -07:00
2026-05-30 07:28:11 -07:00
2026-06-21 12:02:30 -07:00
2026-06-21 17:06:48 -07:00
2026-06-25 09:20:13 +10:00
2026-05-28 22:26:25 -07:00
2026-05-28 22:26:25 -07:00
2026-06-25 13:52:06 -07:00
2026-05-28 22:26:25 -07:00
2026-06-21 20:00:06 -07:00
2026-05-04 15:31:47 -07:00
2026-05-28 22:26:25 -07:00
2026-05-28 22:26:25 -07:00
2026-06-11 19:50:08 -05:00
2026-06-07 03:57:21 -07:00
2026-05-29 22:26:24 +05:30
2026-05-28 22:26:25 -07:00
2026-05-30 07:58:08 -07:00
2026-05-28 22:26:25 -07:00
2026-06-21 16:02:56 +05:30
2026-04-21 05:19:03 -07:00
2026-05-28 22:26:25 -07:00
2026-04-29 20:05:32 -07:00
2026-06-19 11:46:25 -07:00
2026-05-28 22:26:25 -07:00
2026-05-28 22:26:25 -07:00
2026-05-16 13:06:56 -07:00
2026-06-11 04:37:01 -07:00
2026-04-19 16:31:07 -07:00
2026-04-19 16:31:07 -07:00
2026-06-15 04:22:07 -07:00
2026-06-26 00:35:27 -07:00
2026-05-07 05:35:33 -07:00
2026-06-27 04:59:23 +05:30
2026-06-01 19:49:50 -07:00
2026-06-14 02:09:45 -07:00
2026-04-16 21:57:10 -07:00
2026-05-07 07:08:04 -07:00
2026-06-24 00:52:18 +05:30
2026-05-15 14:00:01 -07:00
2026-04-16 21:57:10 -07:00
2026-06-25 23:30:41 +05:30
2026-05-28 22:26:25 -07:00
2026-06-17 07:11:23 -07:00
2026-05-28 22:26:25 -07:00
2026-06-18 10:19:33 -07:00
2026-06-25 00:51:12 +05:30
2026-05-08 09:27:26 -07:00
2026-05-08 09:27:26 -07:00
2026-05-28 22:26:25 -07:00
2026-06-25 02:33:40 +00:00
2026-06-21 11:11:23 -07:00
2026-06-06 18:30:39 -07:00
2026-04-22 14:45:50 -07:00
2026-05-25 15:18:45 -07:00
2026-05-20 01:46:40 -05:00
2026-05-25 06:13:36 -07:00
2026-06-25 14:42:38 -07:00
2026-06-13 14:42:51 -07:00
2026-06-17 13:45:25 -07:00
2026-06-19 11:57:43 -07:00
2026-05-13 17:32:22 -07:00
2026-05-28 22:26:25 -07:00
2026-06-12 00:30:51 -05:00
2026-06-13 14:35:21 -07:00
2026-06-20 23:23:47 -07:00
2026-05-28 22:26:25 -07:00
2026-06-20 10:26:45 -07:00
2026-06-12 01:07:38 -07:00
2026-06-15 05:51:47 -07:00
2026-05-18 22:19:50 -07:00
2026-06-25 21:29:57 -07:00
2026-06-26 01:12:26 +05:30
2026-06-07 23:04:54 -07:00
2026-06-20 10:26:45 -07:00
2026-05-17 02:29:41 -07:00
2026-05-28 22:26:25 -07:00
2026-05-28 22:26:25 -07:00
2026-06-26 12:49:33 -07:00
2026-05-28 22:26:25 -07:00
2026-05-28 22:26:25 -07:00
2026-06-25 22:03:02 -07:00
2026-06-06 18:29:52 -07:00
2026-05-28 22:26:25 -07:00
2026-06-01 01:58:48 -07:00
2026-05-19 14:17:38 -07:00
2026-06-11 18:03:11 -04:00
2026-06-26 11:04:41 -07:00
2026-06-18 12:26:20 +05:30
2026-06-18 08:53:35 -07:00
2026-06-16 13:08:34 -07:00
2026-04-29 21:56:47 -07:00
2026-06-21 16:39:48 -07:00
2026-06-20 23:23:47 -07:00
2026-06-04 18:06:21 -07:00
2026-04-20 03:07:32 -07:00
2026-06-26 12:09:52 +10:00
2026-06-18 09:09:21 +10:00
2026-06-18 14:14:41 +10:00
2026-06-15 13:47:05 +10:00
2026-06-04 11:11:27 +10:00
2026-06-26 12:09:52 +10:00
2026-06-26 12:09:52 +10:00
2026-06-26 12:09:52 +10:00
2026-06-04 12:38:24 +10:00
2026-06-04 10:51:51 +10:00
2026-06-08 22:46:57 -07:00
2026-05-28 22:26:25 -07:00
2026-05-28 22:26:25 -07:00
2026-05-28 22:26:25 -07:00
2026-06-22 15:41:23 +10:00
2026-05-28 22:26:25 -07:00
2026-04-20 23:20:33 -07:00
2026-05-28 22:26:25 -07:00
2026-06-25 16:40:27 -05:00
2026-05-27 00:43:32 -07:00
2026-06-25 23:08:48 +05:30
2026-06-26 00:36:01 -07:00
2026-06-26 15:26:08 +05:30
2026-06-25 23:42:42 +05:30
2026-06-07 18:06:27 -07:00
2026-05-29 13:35:39 +10:00
2026-05-31 00:50:19 -07:00
2026-05-28 22:26:25 -07:00
2026-06-03 06:36:46 -07:00
2026-05-28 22:26:25 -07:00
2026-05-31 17:46:56 -05:00
2026-05-25 01:41:19 -07:00
2026-05-31 17:46:56 -05:00
2026-05-28 22:26:25 -07:00
2026-05-28 22:26:25 -07:00
2026-05-15 12:11:32 -07:00
2026-06-10 02:57:39 -07:00
2026-05-13 17:32:22 -07:00
2026-06-10 02:57:39 -07:00
2026-05-29 13:24:12 -07:00
2026-05-18 22:29:45 -07:00
2026-05-25 05:15:55 -07:00
2026-06-19 07:04:58 -07:00
2026-05-24 18:04:54 -07:00
2026-05-13 22:04:28 -07:00
2026-06-19 07:26:56 -07:00
2026-06-21 13:56:35 -07:00
2026-05-28 22:26:25 -07:00
2026-05-13 16:39:41 -07:00
2026-05-13 16:39:41 -07:00
2026-06-01 19:00:30 -07:00
2026-05-31 00:12:09 -07:00
2026-06-04 18:04:47 -07:00
2026-05-28 22:26:25 -07:00
2026-05-31 00:11:52 -07:00
2026-05-28 22:26:25 -07:00
2026-06-04 18:04:47 -07:00
2026-06-25 01:45:06 +05:30
2026-06-14 16:47:57 -07:00
2026-05-28 04:52:42 -07:00
2026-06-14 16:47:57 -07:00
2026-06-14 16:47:57 -07:00
2026-05-28 04:52:42 -07:00
2026-06-04 18:04:47 -07:00
2026-06-27 03:08:41 +05:30
2026-06-26 17:39:46 +00:00
2026-06-23 03:10:53 +05:30
2026-06-14 02:07:32 -07:00
2026-05-21 02:38:45 +05:30
2026-05-25 03:35:33 -07:00
2026-06-21 11:35:09 -07:00